diff --git a/scripts/update-zfs.sh b/scripts/update-zfs.sh index 2bcc19b18..c175763fe 100755 --- a/scripts/update-zfs.sh +++ b/scripts/update-zfs.sh @@ -1,59 +1,150 @@ #!/bin/bash +# +# WARNING: This script removes the entire zfs subtree and will +# repopulate it using the requested OpenSolaris source release. +# This script should only be used when rebasing the TopGit tree +# against the latest release. +# +trap die_int INT +RELEASE=$1 PROG=update-zfs.sh -ZFS_SRC=http://dlc.sun.com/osol/on/downloads/b89/on-src.tar.bz2 +REMOTE_SRC=http://dlc.sun.com/osol/on/downloads/${RELEASE}/on-src.tar.bz2 die() { - rm -Rf $SRC + rm -Rf ${SRC} echo "${PROG}: $1" >&2 exit 1 } -DEST=`pwd` -if [ `basename $DEST` != "scripts" ]; then +die_int() { + die "Ctrl-C abort" +} + +DST=`pwd` +if [ `basename $DST` != "scripts" ]; then die "Must be run from scripts directory" fi -SRC=`mktemp -d /tmp/zfs.XXXXXXXXXX` -DEST=`dirname $DEST` -DATE=`date +%Y%m%d%H%M%S` +SRC=`mktemp -d /tmp/os-${RELEASE}.XXXXXXXXXX` +DST=`dirname $DST` -wget $ZFS_SRC - -echo "--- Updating ZFS source ---" +echo "----------------------------------------------------------------------" +echo "Remote Source: ${REMOTE_SRC}" +echo "Local Source: ${SRC}" +echo "Local Dest: ${DST}" echo -echo "ZFS_REPO = $ZFS_REPO" -echo "ZFS_PATCH_REPO = $ZFS_PATCH_REPO" -echo "SRC = $SRC" -echo "DEST = $DEST" +echo "------------- Fetching OpenSolaris ${RELEASE} archive ----------------" +wget ${REMOTE_SRC} -P ${SRC} || + die "Error 'wget ${REMOTE_SRC}'" + +echo "------------- Unpacking OperSolaris ${RELEASE} archive ---------------" +tar -xjf ${SRC}/on-src.tar.bz2 -C ${SRC} || + die "Error 'tar -xjf ${SRC}/on-src.tar.bz2 -C ${SRC}'" + +SRC_LIB=${SRC}/usr/src/lib +SRC_CMD=${SRC}/usr/src/cmd +SRC_CM=${SRC}/usr/src/common +SRC_UTS=${SRC}/usr/src/uts +SRC_UCM=${SRC}/usr/src/uts/common +SRC_ZLIB=${SRC}/usr/src/uts/common/fs/zfs + +DST_LIB=${DST}/zfs/lib +DST_CMD=${DST}/zfs/zcmd + +rm -Rf ${DST}/zfs echo -echo "--- Cloning $ZFS_REPO ---" -cd $SRC || die "Failed to 'cd $SRC'" -hg clone $ZFS_REPO || die "Failed to clone $ZFS_REPO" +echo "------------- Updating ZFS from OpenSolaris ${RELEASE} ---------------" +echo "* zfs/lib/libavl" +mkdir -p ${DST_LIB}/libavl/include/sys/ +cp ${SRC_CM}/avl/avl.c ${DST_LIB}/libavl/ +cp ${SRC_UCM}/sys/avl.h ${DST_LIB}/libavl/include/sys/ +cp ${SRC_UCM}/sys/avl_impl.h ${DST_LIB}/libavl/include/sys/ -echo -echo "--- Cloning $ZFS_PATCH_REPO ---" -hg clone $ZFS_PATCH_REPO patches || die "Failed to clone $ZFS_PATCH_REPO" +echo "* zfs/lib/libnvpair" +mkdir -p ${DST_LIB}/libnvpair/include/sys/ +cp ${SRC_CM}/nvpair/nvpair.c ${DST_LIB}/libnvpair/ +cp ${SRC_LIB}/libnvpair/libnvpair.c ${DST_LIB}/libnvpair/ +cp ${SRC_UCM}/os/nvpair_alloc_system.c ${DST_LIB}/libnvpair/ +cp ${SRC_CM}/nvpair/nvpair_alloc_fixed.c ${DST_LIB}/libnvpair/ +cp ${SRC_LIB}/libnvpair/libnvpair.h ${DST_LIB}/libnvpair/include/ +cp ${SRC_UCM}/sys/nvpair.h ${DST_LIB}/libnvpair/include/sys/ +cp ${SRC_UCM}/sys/nvpair_impl.h ${DST_LIB}/libnvpair/include/sys/ -echo -echo "--- Backing up existing files ---" -echo "$DEST/zfs -> $DEST/zfs.$DATE" -cp -Rf $DEST/zfs $DEST/zfs.$DATE || die "Failed to backup" -echo "$DEST/zfs_patches -> $DEST/zfs_patches.$DATE" -cp -Rf $DEST/zfs_patches $DEST/zfs_patches.$DATE || die "Failed to backup" +echo "* zfs/lib/libumem" +mkdir -p ${DST_LIB}/libumem/include/ +mkdir -p ${DST_LIB}/libumem/sys/ +cp ${SRC_LIB}/libumem/common/*.c ${DST_LIB}/libumem/ +cp ${SRC_LIB}/libumem/common/*.h ${DST_LIB}/libumem/include/ +cp ${SRC_LIB}/libumem/common/sys/*.h ${DST_LIB}/libumem/sys/ -echo -echo "--- Overwriting $DEST/zfs and $DEST/zfs_patches ---" -find $SRC/trunk/src/ -name SConstruct -type f -print | xargs /bin/rm -f -find $SRC/trunk/src/ -name SConscript -type f -print | xargs /bin/rm -f -find $SRC/trunk/src/ -name *.orig -type f -print | xargs /bin/rm -f -rm -f $SRC/trunk/src/myconfig.py -cp -Rf $SRC/trunk/src/* $DEST/zfs || die "Failed to overwrite" -cp -Rf $SRC/patches/*.patch $DEST/zfs_patches/patches/ || die "Failed to overwrite" -cp -f $SRC/patches/series $DEST/zfs_patches/series/zfs-lustre +echo "* zfs/lib/libuutil" +mkdir -p ${DST_LIB}/libuutil/include/ +cp ${SRC_LIB}/libuutil/common/*.c ${DST_LIB}/libuutil/ +cp ${SRC_LIB}/libuutil/common/*.h ${DST_LIB}/libuutil/include/ -echo -echo "--- Removing $SRC ---" -rm -Rf $SRC +echo "* zfs/lib/libspl" +mkdir -p ${DST_LIB}/libspl/include/sys/ +cp ${SRC_LIB}/libzpool/common/kernel.c ${DST_LIB}/libspl/ +cp ${SRC_LIB}/libzpool/common/taskq.c ${DST_LIB}/libspl/ +cp ${SRC_LIB}/libzpool/common/util.c ${DST_LIB}/libspl/ +cp ${SRC_LIB}/libc/port/gen/strlcat.c ${DST_LIB}/libspl/ +cp ${SRC_LIB}/libc/port/gen/strlcpy.c ${DST_LIB}/libspl/ +cp ${SRC_LIB}/libc/port/gen/strnlen.c ${DST_LIB}/libspl/ +cp ${SRC_LIB}/libgen/common/mkdirp.c ${DST_LIB}/libspl/ +cp ${SRC_CM}/unicode/u8_textprep.c ${DST_LIB}/libspl/ +cp ${SRC_UCM}/os/list.c ${DST_LIB}/libspl/ +cp ${SRC_UCM}/sys/vmem.h ${DST_LIB}/libspl/include/sys/ +cp ${SRC_UCM}/sys/list.h ${DST_LIB}/libspl/include/sys/ +cp ${SRC_UCM}/sys/list_impl.h ${DST_LIB}/libspl/include/sys/ +echo "* zfs/lib/libzcommon" +mkdir -p ${DST_LIB}/libzcommon/include/sys/fs/ +mkdir -p ${DST_LIB}/libzcommon/include/sys/fm/fs/ +cp ${SRC_CM}/zfs/*.c ${DST_LIB}/libzcommon/ +cp ${SRC_CM}/zfs/*.h ${DST_LIB}/libzcommon/include/ +cp ${SRC_UCM}/sys/fs/zfs.h ${DST_LIB}/libzcommon/include/sys/fs/ +cp ${SRC_UCM}/sys/fm/fs/zfs.h ${DST_LIB}/libzcommon/include/sys/fm/fs/ + +echo "* zfs/lib/libzpool" +mkdir -p ${DST_LIB}/libzpool/include/sys/ +cp ${SRC_ZLIB}/*.c ${DST_LIB}/libzpool/ +cp ${SRC_UTS}/intel/zfs/spa_boot.c ${DST_LIB}/libzpool/ +cp ${SRC_ZLIB}/sys/*.h ${DST_LIB}/libzpool/include/sys/ +rm ${DST_LIB}/libzpool/vdev_disk.c +rm ${DST_LIB}/libzpool/include/sys/vdev_disk.h + +echo "* zfs/lib/libzfs" +mkdir -p ${DST_LIB}/libzfs/include/ +cp ${SRC_LIB}/libzfs/common/*.c ${DST_LIB}/libzfs/ +cp ${SRC_LIB}/libzfs/common/*.h ${DST_LIB}/libzfs/include/ + +echo "* zfs/zcmd/zpool" +mkdir -p ${DST_CMD}/zpool +cp ${SRC_CMD}/zpool/*.c ${DST_CMD}/zpool/ +cp ${SRC_CMD}/zpool/*.h ${DST_CMD}/zpool/ + +echo "* zfs/zcmd/zfs" +mkdir -p ${DST_CMD}/zfs +cp ${SRC_CMD}/zfs/*.c ${DST_CMD}/zfs/ +cp ${SRC_CMD}/zfs/*.h ${DST_CMD}/zfs/ + +echo "* zfs/zcmd/zdb" +mkdir -p ${DST_CMD}/zdb/ +cp ${SRC_CMD}/zdb/*.c ${DST_CMD}/zdb/ + +echo "* zfs/zcmd/zdump" +mkdir -p ${DST_CMD}/zdump +cp ${SRC_CMD}/zdump/*.c ${DST_CMD}/zdump/ + +echo "* zfs/zcmd/zinject" +mkdir -p ${DST_CMD}/zinject +cp ${SRC_CMD}/zinject/*.c ${DST_CMD}/zinject/ +cp ${SRC_CMD}/zinject/*.h ${DST_CMD}/zinject/ + +echo "* zfs/zcmd/ztest" +mkdir -p ${DST_CMD}/ztest +cp ${SRC_CMD}/ztest/*.c ${DST_CMD}/ztest/ + +rm -Rf ${SRC} diff --git a/zfs/lib/libavl/avl.c b/zfs/lib/libavl/avl.c index ff3ad52b7..c9727c643 100644 --- a/zfs/lib/libavl/avl.c +++ b/zfs/lib/libavl/avl.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" /* @@ -808,6 +808,64 @@ avl_remove(avl_tree_t *tree, void *data) } while (parent != NULL); } +#define AVL_REINSERT(tree, obj) \ + avl_remove((tree), (obj)); \ + avl_add((tree), (obj)) + +boolean_t +avl_update_lt(avl_tree_t *t, void *obj) +{ + void *neighbor; + + ASSERT(((neighbor = AVL_NEXT(t, obj)) == NULL) || + (t->avl_compar(obj, neighbor) <= 0)); + + neighbor = AVL_PREV(t, obj); + if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) { + AVL_REINSERT(t, obj); + return (B_TRUE); + } + + return (B_FALSE); +} + +boolean_t +avl_update_gt(avl_tree_t *t, void *obj) +{ + void *neighbor; + + ASSERT(((neighbor = AVL_PREV(t, obj)) == NULL) || + (t->avl_compar(obj, neighbor) >= 0)); + + neighbor = AVL_NEXT(t, obj); + if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) { + AVL_REINSERT(t, obj); + return (B_TRUE); + } + + return (B_FALSE); +} + +boolean_t +avl_update(avl_tree_t *t, void *obj) +{ + void *neighbor; + + neighbor = AVL_PREV(t, obj); + if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) { + AVL_REINSERT(t, obj); + return (B_TRUE); + } + + neighbor = AVL_NEXT(t, obj); + if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) { + AVL_REINSERT(t, obj); + return (B_TRUE); + } + + return (B_FALSE); +} + /* * initialize a new AVL tree */ @@ -853,6 +911,12 @@ avl_numnodes(avl_tree_t *tree) return (tree->avl_numnodes); } +boolean_t +avl_is_empty(avl_tree_t *tree) +{ + ASSERT(tree); + return (tree->avl_numnodes == 0); +} #define CHILDBIT (1L) diff --git a/zfs/lib/libavl/include/sys/avl.h b/zfs/lib/libavl/include/sys/avl.h index 1c1f11b2b..02263a5a0 100644 --- a/zfs/lib/libavl/include/sys/avl.h +++ b/zfs/lib/libavl/include/sys/avl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _AVL_H #define _AVL_H - +#pragma ident "%Z%%M% %I% %E% SMI" /* * This is a private header file. Applications should not directly include @@ -38,6 +37,7 @@ extern "C" { #endif +#include #include /* @@ -128,7 +128,6 @@ typedef uintptr_t avl_index_t; #define AVL_AFTER (1) - /* * Prototypes * @@ -182,7 +181,7 @@ extern void avl_insert(avl_tree_t *tree, void *node, avl_index_t where); * data to avoid doing avl_find() again for insertion. * * new_data - new data to insert - * here - existing node in "tree" + * here - existing node in "tree" * direction - either AVL_AFTER or AVL_BEFORE the data "here". */ extern void avl_insert_here(avl_tree_t *tree, void *new_data, void *here, @@ -251,12 +250,26 @@ extern void avl_add(avl_tree_t *tree, void *node); */ extern void avl_remove(avl_tree_t *tree, void *node); +/* + * Reinsert a node only if its order has changed relative to its nearest + * neighbors. To optimize performance avl_update_lt() checks only the previous + * node and avl_update_gt() checks only the next node. Use avl_update_lt() and + * avl_update_gt() only if you know the direction in which the order of the + * node may change. + */ +extern boolean_t avl_update(avl_tree_t *, void *); +extern boolean_t avl_update_lt(avl_tree_t *, void *); +extern boolean_t avl_update_gt(avl_tree_t *, void *); /* * Return the number of nodes in the tree */ extern ulong_t avl_numnodes(avl_tree_t *tree); +/* + * Return B_TRUE if there are zero nodes in the tree, B_FALSE otherwise. + */ +extern boolean_t avl_is_empty(avl_tree_t *tree); /* * Used to destroy any remaining nodes in a tree. The cookie argument should diff --git a/zfs/lib/libavl/include/sys/avl_impl.h b/zfs/lib/libavl/include/sys/avl_impl.h index fddf76906..620685f37 100644 --- a/zfs/lib/libavl/include/sys/avl_impl.h +++ b/zfs/lib/libavl/include/sys/avl_impl.h @@ -27,7 +27,7 @@ #ifndef _AVL_IMPL_H #define _AVL_IMPL_H - +#pragma ident "%Z%%M% %I% %E% SMI" /* * This is a private header file. Applications should not directly include diff --git a/zfs/lib/libdmu-ctl/dctl_client.c b/zfs/lib/libdmu-ctl/dctl_client.c deleted file mode 100644 index e3d8f305b..000000000 --- a/zfs/lib/libdmu-ctl/dctl_client.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * Try to connect to the socket given in path. - * - * For nftw() convenience, returns 0 if unsuccessful, otherwise - * returns the socket descriptor. - */ -static int try_connect(const char *path) -{ - struct sockaddr_un name; - int sock; - - sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock == -1) { - perror("socket"); - return 0; - } - - /* - * The socket fd cannot be 0 otherwise nftw() will not interpret the - * return code correctly. - */ - VERIFY(sock != 0); - - name.sun_family = AF_UNIX; - strncpy(name.sun_path, path, sizeof(name.sun_path)); - - name.sun_path[sizeof(name.sun_path) - 1] = '\0'; - - if (connect(sock, (struct sockaddr *) &name, sizeof(name)) == -1) { - close(sock); - return 0; - } - - return sock; -} - -/* - * nftw() callback. - */ -static int nftw_cb(const char *fpath, const struct stat *sb, int typeflag, - struct FTW *ftwbuf) -{ - if (!S_ISSOCK(sb->st_mode)) - return 0; - - if (strcmp(&fpath[ftwbuf->base], SOCKNAME) != 0) - return 0; - - return try_connect(fpath); -} - -/* - * For convenience, if check_subdirs is true we walk the directory tree to - * find a good socket. - */ -int dctlc_connect(const char *dir, boolean_t check_subdirs) -{ - char *fpath; - int fd; - - if (check_subdirs) - fd = nftw(dir, nftw_cb, 10, FTW_PHYS); - else { - fpath = malloc(strlen(dir) + strlen(SOCKNAME) + 2); - if (fpath == NULL) - return -1; - - strcpy(fpath, dir); - strcat(fpath, "/" SOCKNAME); - - fd = try_connect(fpath); - - free(fpath); - } - - return fd == 0 ? -1 : fd; -} - -void dctlc_disconnect(int fd) -{ - (void) shutdown(fd, SHUT_RDWR); -} - -static int dctl_reply_copyin(int fd, dctl_cmd_t *cmd) -{ - return dctl_send_data(fd, (void *)(uintptr_t) cmd->u.dcmd_copy.ptr, - cmd->u.dcmd_copy.size); -} - -static int dctl_reply_copyinstr(int fd, dctl_cmd_t *cmd) -{ - dctl_cmd_t reply; - char *from; - size_t len, buflen, to_copy; - int error; - - reply.dcmd_msg = DCTL_GEN_REPLY; - - from = (char *)(uintptr_t) cmd->u.dcmd_copy.ptr; - - buflen = cmd->u.dcmd_copy.size; - to_copy = strnlen(from, buflen - 1); - - reply.u.dcmd_reply.rc = from[to_copy] == '\0' ? 0 : ENAMETOOLONG; - reply.u.dcmd_reply.size = to_copy; - - error = dctl_send_msg(fd, &reply); - - if (!error && to_copy > 0) - error = dctl_send_data(fd, from, to_copy); - - return error; -} - -static int dctl_reply_copyout(int fd, dctl_cmd_t *cmd) -{ - return dctl_read_data(fd, (void *)(uintptr_t) cmd->u.dcmd_copy.ptr, - cmd->u.dcmd_copy.size); -} - -static int dctl_reply_fd_read(int fd, dctl_cmd_t *cmd) -{ - dctl_cmd_t reply; - void *buf; - int error; - ssize_t rrc, size = cmd->u.dcmd_fd_io.size; - - buf = malloc(size); - if (buf == NULL) - return ENOMEM; - - rrc = read(cmd->u.dcmd_fd_io.fd, buf, size); - - reply.dcmd_msg = DCTL_GEN_REPLY; - reply.u.dcmd_reply.rc = rrc == -1 ? errno : 0; - reply.u.dcmd_reply.size = rrc; - - error = dctl_send_msg(fd, &reply); - - if (!error && rrc > 0) - error = dctl_send_data(fd, buf, rrc); - -out: - free(buf); - - return error; -} - -static int dctl_reply_fd_write(int fd, dctl_cmd_t *cmd) -{ - dctl_cmd_t reply; - void *buf; - int error; - ssize_t wrc, size = cmd->u.dcmd_fd_io.size; - - buf = malloc(size); - if (buf == NULL) - return ENOMEM; - - error = dctl_read_data(fd, buf, size); - if (error) - goto out; - - wrc = write(cmd->u.dcmd_fd_io.fd, buf, size); - - reply.dcmd_msg = DCTL_GEN_REPLY; - reply.u.dcmd_reply.rc = wrc == -1 ? errno : 0; - reply.u.dcmd_reply.size = wrc; - - error = dctl_send_msg(fd, &reply); - -out: - free(buf); - - return error; -} - -int dctlc_ioctl(int fd, int32_t request, void *arg) -{ - int error; - dctl_cmd_t cmd; - - ASSERT(fd != 0); - - cmd.dcmd_msg = DCTL_IOCTL; - - cmd.u.dcmd_ioctl.cmd = request; - cmd.u.dcmd_ioctl.arg = (uintptr_t) arg; - - error = dctl_send_msg(fd, &cmd); - - while (!error && (error = dctl_read_msg(fd, &cmd)) == 0) { - switch (cmd.dcmd_msg) { - case DCTL_IOCTL_REPLY: - error = cmd.u.dcmd_reply.rc; - goto out; - case DCTL_COPYIN: - error = dctl_reply_copyin(fd, &cmd); - break; - case DCTL_COPYINSTR: - error = dctl_reply_copyinstr(fd, &cmd); - break; - case DCTL_COPYOUT: - error = dctl_reply_copyout(fd, &cmd); - break; - case DCTL_FD_READ: - error = dctl_reply_fd_read(fd, &cmd); - break; - case DCTL_FD_WRITE: - error = dctl_reply_fd_write(fd, &cmd); - break; - default: - fprintf(stderr, "%s(): invalid message " - "received.\n", __func__); - error = EINVAL; - goto out; - } - } - -out: - errno = error; - return error ? -1 : 0; -} diff --git a/zfs/lib/libdmu-ctl/dctl_common.c b/zfs/lib/libdmu-ctl/dctl_common.c deleted file mode 100644 index 8de37dcb1..000000000 --- a/zfs/lib/libdmu-ctl/dctl_common.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include -#include -#include -#include - -#include -#include - -int dctl_read_msg(int fd, dctl_cmd_t *cmd) -{ - int error; - - /* - * First, read only the magic number and the protocol version. - * - * This prevents blocking forever in case the size of dctl_cmd_t - * shrinks in future protocol versions. - */ - error = dctl_read_data(fd, cmd, DCTL_CMD_HEADER_SIZE); - - if (!error &&cmd->dcmd_magic != DCTL_MAGIC) { - fprintf(stderr, "%s(): invalid magic number\n", __func__); - error = EIO; - } - - if (!error && cmd->dcmd_version != DCTL_PROTOCOL_VER) { - fprintf(stderr, "%s(): invalid protocol version\n", __func__); - error = ENOTSUP; - } - - if (error) - return error; - - /* Get the rest of the command */ - return dctl_read_data(fd, (caddr_t) cmd + DCTL_CMD_HEADER_SIZE, - sizeof(dctl_cmd_t) - DCTL_CMD_HEADER_SIZE); -} - -int dctl_send_msg(int fd, dctl_cmd_t *cmd) -{ - cmd->dcmd_magic = DCTL_MAGIC; - cmd->dcmd_version = DCTL_PROTOCOL_VER; - - return dctl_send_data(fd, cmd, sizeof(dctl_cmd_t)); -} - -int dctl_read_data(int fd, void *ptr, size_t size) -{ - size_t read = 0; - size_t left = size; - ssize_t rc; - - while (left > 0) { - rc = recv(fd, (caddr_t) ptr + read, left, 0); - - /* File descriptor closed */ - if (rc == 0) - return ECONNRESET; - - if (rc == -1) { - if (errno == EINTR) - continue; - return errno; - } - - read += rc; - left -= rc; - } - - return 0; -} - -int dctl_send_data(int fd, const void *ptr, size_t size) -{ - ssize_t rc; - - do { - rc = send(fd, ptr, size, MSG_NOSIGNAL); - } while(rc == -1 && errno == EINTR); - - return rc == size ? 0 : EIO; -} - diff --git a/zfs/lib/libdmu-ctl/dctl_server.c b/zfs/lib/libdmu-ctl/dctl_server.c deleted file mode 100644 index 016278509..000000000 --- a/zfs/lib/libdmu-ctl/dctl_server.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static dctl_sock_info_t ctl_sock = { - .dsi_mtx = PTHREAD_MUTEX_INITIALIZER, - .dsi_fd = -1 -}; - -static int dctl_create_socket_common(); - -/* - * Routines from zfs_ioctl.c - */ -extern int zfs_ioctl_init(); -extern int zfs_ioctl_fini(); -extern int zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, - int *rvalp); - -/* - * We can't simply put the client file descriptor in wthr_info_t because we - * have no way of accessing it from the DMU code without extensive - * modifications. - * - * Therefore each worker thread will have it's own global thread-specific - * client_fd variable. - */ -static __thread int client_fd = -1; - -int dctls_copyin(const void *src, void *dest, size_t size) -{ - dctl_cmd_t cmd; - - VERIFY(client_fd >= 0); - - cmd.dcmd_msg = DCTL_COPYIN; - cmd.u.dcmd_copy.ptr = (uintptr_t) src; - cmd.u.dcmd_copy.size = size; - - if (dctl_send_msg(client_fd, &cmd) != 0) - return EFAULT; - - if (dctl_read_data(client_fd, dest, size) != 0) - return EFAULT; - - return 0; -} - -int dctls_copyinstr(const char *from, char *to, size_t max, size_t *len) -{ - dctl_cmd_t msg; - size_t copied; - - VERIFY(client_fd >= 0); - - if (max == 0) - return ENAMETOOLONG; - if (max < 0) - return EFAULT; - - msg.dcmd_msg = DCTL_COPYINSTR; - msg.u.dcmd_copy.ptr = (uintptr_t) from; - msg.u.dcmd_copy.size = max; - - if (dctl_send_msg(client_fd, &msg) != 0) - return EFAULT; - - if (dctl_read_msg(client_fd, &msg) != 0) - return EFAULT; - - if (msg.dcmd_msg != DCTL_GEN_REPLY) - return EFAULT; - - copied = msg.u.dcmd_reply.size; - - if (copied >= max) - return EFAULT; - - if (copied > 0) - if (dctl_read_data(client_fd, to, copied) != 0) - return EFAULT; - - to[copied] = '\0'; - - if (len != NULL) - *len = copied + 1; - - return msg.u.dcmd_reply.rc; -} - -int dctls_copyout(const void *src, void *dest, size_t size) -{ - dctl_cmd_t cmd; - - VERIFY(client_fd >= 0); - - cmd.dcmd_msg = DCTL_COPYOUT; - cmd.u.dcmd_copy.ptr = (uintptr_t) dest; - cmd.u.dcmd_copy.size = size; - - if (dctl_send_msg(client_fd, &cmd) != 0) - return EFAULT; - - if (dctl_send_data(client_fd, src, size) != 0) - return EFAULT; - - return 0; -} - -int dctls_fd_read(int fd, void *buf, ssize_t len, ssize_t *residp) -{ - dctl_cmd_t msg; - uint64_t dsize; - int error; - - VERIFY(client_fd >= 0); - - msg.dcmd_msg = DCTL_FD_READ; - msg.u.dcmd_fd_io.fd = fd; - msg.u.dcmd_fd_io.size = len; - - if ((error = dctl_send_msg(client_fd, &msg)) != 0) - return error; - - if ((error = dctl_read_msg(client_fd, &msg)) != 0) - return error; - - if (msg.dcmd_msg != DCTL_GEN_REPLY) - return EIO; - - if (msg.u.dcmd_reply.rc != 0) - return msg.u.dcmd_reply.rc; - - dsize = msg.u.dcmd_reply.size; - - if (dsize > 0) - error = dctl_read_data(client_fd, buf, dsize); - - *residp = len - dsize; - - return error; -} - -int dctls_fd_write(int fd, const void *src, ssize_t len) -{ - dctl_cmd_t msg; - int error; - - VERIFY(client_fd >= 0); - - msg.dcmd_msg = DCTL_FD_WRITE; - msg.u.dcmd_fd_io.fd = fd; - msg.u.dcmd_fd_io.size = len; - - error = dctl_send_msg(client_fd, &msg); - - if (!error) - error = dctl_send_data(client_fd, src, len); - - if (!error) - error = dctl_read_msg(client_fd, &msg); - - if (error) - return error; - - if (msg.dcmd_msg != DCTL_GEN_REPLY) - return EIO; - - if (msg.u.dcmd_reply.rc != 0) - return msg.u.dcmd_reply.rc; - - /* - * We have to do this because the original upstream code - * does not check if residp == len. - */ - if (msg.u.dcmd_reply.size != len) - return EIO; - - return 0; -} - -/* Handle a new connection */ -static void dctl_handle_conn(int sock_fd) -{ - dctl_cmd_t cmd; - dev_t dev = { 0 }; - int rc; - - client_fd = sock_fd; - - while (dctl_read_msg(sock_fd, &cmd) == 0) { - if (cmd.dcmd_msg != DCTL_IOCTL) { - fprintf(stderr, "%s(): unexpected message type.\n", - __func__); - break; - } - - rc = zfsdev_ioctl(dev, cmd.u.dcmd_ioctl.cmd, - (intptr_t) cmd.u.dcmd_ioctl.arg, 0, NULL, NULL); - - cmd.dcmd_msg = DCTL_IOCTL_REPLY; - cmd.u.dcmd_reply.rc = rc; - - if (dctl_send_msg(sock_fd, &cmd) != 0) - break; - } - close(sock_fd); - - client_fd = -1; -} - -/* Main worker thread loop */ -static void *dctl_thread(void *arg) -{ - wthr_info_t *thr = arg; - struct pollfd fds[1]; - - fds[0].events = POLLIN; - - pthread_mutex_lock(&ctl_sock.dsi_mtx); - - while (!thr->wthr_exit) { - /* Clean-up dead threads */ - dctl_thr_join(); - - /* The file descriptor might change in the thread lifetime */ - fds[0].fd = ctl_sock.dsi_fd; - - /* Poll socket with 1-second timeout */ - int rc = poll(fds, 1, 1000); - if (rc == 0 || (rc == -1 && errno == EINTR)) - continue; - - /* Recheck the exit flag */ - if (thr->wthr_exit) - break; - - if (rc == -1) { - /* Unknown error, let's try to recreate the socket */ - close(ctl_sock.dsi_fd); - ctl_sock.dsi_fd = -1; - - if (dctl_create_socket_common() != 0) - break; - - continue; - } - ASSERT(rc == 1); - - short rev = fds[0].revents; - if (rev == 0) - continue; - ASSERT(rev == POLLIN); - - /* - * At this point there should be a connection ready to be - * accepted. - */ - int client_fd = accept(ctl_sock.dsi_fd, NULL, NULL); - /* Many possible errors here, we'll just retry */ - if (client_fd == -1) - continue; - - /* - * Now lets handle the request. This can take a very - * long time (hours even), so we'll let other threads - * handle new connections. - */ - pthread_mutex_unlock(&ctl_sock.dsi_mtx); - - dctl_thr_rebalance(thr, B_FALSE); - dctl_handle_conn(client_fd); - dctl_thr_rebalance(thr, B_TRUE); - - pthread_mutex_lock(&ctl_sock.dsi_mtx); - } - pthread_mutex_unlock(&ctl_sock.dsi_mtx); - - dctl_thr_die(thr); - - return NULL; -} - -static int dctl_create_socket_common() -{ - dctl_sock_info_t *s = &ctl_sock; - size_t size; - int error; - - ASSERT(s->dsi_fd == -1); - - /* - * Unlink old socket, in case it exists. - * We don't care about errors here. - */ - unlink(s->dsi_path); - - /* Create the socket */ - s->dsi_fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (s->dsi_fd == -1) { - error = errno; - perror("socket"); - return error; - } - - s->dsi_addr.sun_family = AF_UNIX; - - size = sizeof(s->dsi_addr.sun_path) - 1; - strncpy(s->dsi_addr.sun_path, s->dsi_path, size); - - s->dsi_addr.sun_path[size] = '\0'; - - if (bind(s->dsi_fd, (struct sockaddr *) &s->dsi_addr, - sizeof(s->dsi_addr)) != 0) { - error = errno; - perror("bind"); - return error; - } - - if (listen(s->dsi_fd, LISTEN_BACKLOG) != 0) { - error = errno; - perror("listen"); - unlink(s->dsi_path); - return error; - } - - return 0; -} - -static int dctl_create_socket(const char *cfg_dir) -{ - int error; - dctl_sock_info_t *s = &ctl_sock; - - ASSERT(s->dsi_path == NULL); - ASSERT(s->dsi_fd == -1); - - int pathsize = strlen(cfg_dir) + strlen(SOCKNAME) + 2; - if (pathsize > sizeof(s->dsi_addr.sun_path)) - return ENAMETOOLONG; - - s->dsi_path = malloc(pathsize); - if (s->dsi_path == NULL) - return ENOMEM; - - strcpy(s->dsi_path, cfg_dir); - strcat(s->dsi_path, "/" SOCKNAME); - - /* - * For convenience, create the directory in case it doesn't exist. - * We don't care about errors here. - */ - mkdir(cfg_dir, 0770); - - error = dctl_create_socket_common(); - - if (error) { - free(s->dsi_path); - - if (s->dsi_fd != -1) { - close(s->dsi_fd); - s->dsi_fd = -1; - } - } - - return error; -} - -static void dctl_destroy_socket() -{ - dctl_sock_info_t *s = &ctl_sock; - - ASSERT(s->dsi_path != NULL); - ASSERT(s->dsi_fd != -1); - - close(s->dsi_fd); - s->dsi_fd = -1; - - unlink(s->dsi_path); - free(s->dsi_path); -} - -/* - * Initialize the DMU userspace control interface. - * This should be called after kernel_init(). - * - * Note that only very rarely we have more than a couple of simultaneous - * lzfs/lzpool connections. Since the thread pool grows automatically when all - * threads are busy, a good value for min_thr and max_free_thr is 2. - */ -int dctl_server_init(const char *cfg_dir, int min_thr, int max_free_thr) -{ - int error; - - ASSERT(min_thr > 0); - ASSERT(max_free_thr >= min_thr); - - error = zfs_ioctl_init(); - if (error) - return error; - - error = dctl_create_socket(cfg_dir); - if (error) { - (void) zfs_ioctl_fini(); - return error; - } - - error = dctl_thr_pool_create(min_thr, max_free_thr, dctl_thread); - if (error) { - (void) zfs_ioctl_fini(); - dctl_destroy_socket(); - return error; - } - - return 0; -} - -/* - * Terminate control interface. - * This should be called after closing all objsets, but before calling - * kernel_fini(). - * May return EBUSY if the SPA is busy. - * - * Thread pool destruction can take a while due to poll() - * timeout or due to a thread being busy (e.g. a backup is being taken). - */ -int dctl_server_fini() -{ - dctl_thr_pool_stop(); - dctl_destroy_socket(); - - return zfs_ioctl_fini(); -} diff --git a/zfs/lib/libdmu-ctl/dctl_thrpool.c b/zfs/lib/libdmu-ctl/dctl_thrpool.c deleted file mode 100644 index 7b2f9b4c2..000000000 --- a/zfs/lib/libdmu-ctl/dctl_thrpool.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static dctl_thr_info_t thr_pool = { - .dti_mtx = PTHREAD_MUTEX_INITIALIZER -}; - -/* - * Create n threads. - * Callers must acquire thr_pool.dti_mtx first. - */ -static int dctl_thr_create(int n) -{ - dctl_thr_info_t *p = &thr_pool; - int error; - - for (int i = 0; i < n; i++) { - wthr_info_t *thr = malloc(sizeof(wthr_info_t)); - if (thr == NULL) - return ENOMEM; - - thr->wthr_exit = B_FALSE; - thr->wthr_free = B_TRUE; - - error = pthread_create(&thr->wthr_id, NULL, p->dti_thr_func, - thr); - if (error) { - free(thr); - return error; - } - - p->dti_free++; - - list_insert_tail(&p->dti_list, thr); - } - return 0; -} - -/* - * Mark the thread as dead. - * Must be called right before exiting the main thread function. - */ -void dctl_thr_die(wthr_info_t *thr) -{ - dctl_thr_info_t *p = &thr_pool; - - thr->wthr_exit = B_TRUE; - dctl_thr_rebalance(thr, B_FALSE); - - pthread_mutex_lock(&p->dti_mtx); - - list_remove(&p->dti_list, thr); - list_insert_tail(&p->dti_join_list, thr); - - pthread_mutex_unlock(&p->dti_mtx); -} - -/* - * Clean-up dead threads. - */ -void dctl_thr_join() -{ - dctl_thr_info_t *p = &thr_pool; - wthr_info_t *thr; - - pthread_mutex_lock(&p->dti_mtx); - - while ((thr = list_head(&p->dti_join_list))) { - list_remove(&p->dti_join_list, thr); - - ASSERT(!pthread_equal(thr->wthr_id, pthread_self())); - - /* - * This should not block because all the threads - * on this list should have died already. - * - * pthread_join() can only return an error if - * we made a programming mistake. - */ - VERIFY(pthread_join(thr->wthr_id, NULL) == 0); - - ASSERT(thr->wthr_exit); - ASSERT(!thr->wthr_free); - - free(thr); - } - - pthread_mutex_unlock(&p->dti_mtx); -} - -/* - * Adjust the number of free threads in the pool and the thread status. - * - * Callers must acquire thr_pool.dti_mtx first. - */ -static void dctl_thr_adjust_free(wthr_info_t *thr, boolean_t set_free) -{ - dctl_thr_info_t *p = &thr_pool; - - ASSERT(p->dti_free >= 0); - - if (!thr->wthr_free && set_free) - p->dti_free++; - else if (thr->wthr_free && !set_free) - p->dti_free--; - - ASSERT(p->dti_free >= 0); - - thr->wthr_free = set_free; -} - -/* - * Rebalance threads. Also adjusts the free status of the thread. - * Will set the thread exit flag if the number of free threads is above - * the limit. - */ -void dctl_thr_rebalance(wthr_info_t *thr, boolean_t set_free) -{ - dctl_thr_info_t *p = &thr_pool; - - pthread_mutex_lock(&p->dti_mtx); - - if (p->dti_exit || p->dti_free > p->dti_max_free) - thr->wthr_exit = B_TRUE; - - if (thr->wthr_exit) - set_free = B_FALSE; - - dctl_thr_adjust_free(thr, set_free); - - if (!p->dti_exit && p->dti_free == 0) - dctl_thr_create(1); - - pthread_mutex_unlock(&p->dti_mtx); -} - -/* - * Stop the thread pool. - * - * This can take a while since it actually waits for all threads to exit. - */ -void dctl_thr_pool_stop() -{ - dctl_thr_info_t *p = &thr_pool; - wthr_info_t *thr; - struct timespec ts; - - pthread_mutex_lock(&p->dti_mtx); - - ASSERT(!p->dti_exit); - p->dti_exit = B_TRUE; - - /* Let's flag the threads first */ - thr = list_head(&p->dti_list); - while (thr != NULL) { - thr->wthr_exit = B_TRUE; - dctl_thr_adjust_free(thr, B_FALSE); - - thr = list_next(&p->dti_list, thr); - } - - pthread_mutex_unlock(&p->dti_mtx); - - /* Now let's wait for them to exit */ - ts.tv_sec = 0; - ts.tv_nsec = 50000000; /* 50ms */ - do { - nanosleep(&ts, NULL); - - pthread_mutex_lock(&p->dti_mtx); - thr = list_head(&p->dti_list); - pthread_mutex_unlock(&p->dti_mtx); - - dctl_thr_join(); - } while(thr != NULL); - - ASSERT(p->dti_free == 0); - - ASSERT(list_is_empty(&p->dti_list)); - ASSERT(list_is_empty(&p->dti_join_list)); - - list_destroy(&p->dti_list); - list_destroy(&p->dti_join_list); -} - -/* - * Create thread pool. - * - * If at least one thread creation fails, it will stop all previous - * threads and return a non-zero value. - */ -int dctl_thr_pool_create(int min_thr, int max_free_thr, - thr_func_t *thr_func) -{ - int error; - dctl_thr_info_t *p = &thr_pool; - - ASSERT(p->dti_free == 0); - - /* Initialize global variables */ - p->dti_min = min_thr; - p->dti_max_free = max_free_thr; - p->dti_exit = B_FALSE; - p->dti_thr_func = thr_func; - - list_create(&p->dti_list, sizeof(wthr_info_t), offsetof(wthr_info_t, - wthr_node)); - list_create(&p->dti_join_list, sizeof(wthr_info_t), - offsetof(wthr_info_t, wthr_node)); - - pthread_mutex_lock(&p->dti_mtx); - error = dctl_thr_create(min_thr); - pthread_mutex_unlock(&p->dti_mtx); - - if (error) - dctl_thr_pool_stop(); - - return error; -} diff --git a/zfs/lib/libdmu-ctl/include/sys/dmu_ctl.h b/zfs/lib/libdmu-ctl/include/sys/dmu_ctl.h deleted file mode 100644 index c2044ba27..000000000 --- a/zfs/lib/libdmu-ctl/include/sys/dmu_ctl.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DMU_CTL_H -#define _SYS_DMU_CTL_H - -#include - -/* Default directory where the clients search for sockets to connect */ -#define DMU_CTL_DEFAULT_DIR "/var/run/zfs/udmu" - -/* - * These functions are called by the server process. - * - * kernel_init() must be called before dctl_server_init(). - * kernel_fini() must not be called before dctl_server_fini(). - * - * All objsets must be closed and object references be released before calling - * dctl_server_fini(), otherwise it will return EBUSY. - * - * Note: On Solaris, it is highly recommended to either catch or ignore the - * SIGPIPE signal, otherwise the server process will die if the client is - * killed. - */ -int dctl_server_init(const char *cfg_dir, int min_threads, - int max_free_threads); -int dctl_server_fini(); - -/* - * The following functions are called by the DMU from the server process context - * (in the worker threads). - */ -int dctls_copyin(const void *src, void *dest, size_t size); -int dctls_copyinstr(const char *from, char *to, size_t max, - size_t *len); -int dctls_copyout(const void *src, void *dest, size_t size); -int dctls_fd_read(int fd, void *buf, ssize_t len, ssize_t *residp); -int dctls_fd_write(int fd, const void *src, ssize_t len); - -/* - * These functions are called by the client process (libzfs). - */ -int dctlc_connect(const char *dir, boolean_t check_subdirs); -void dctlc_disconnect(int fd); - -int dctlc_ioctl(int fd, int32_t request, void *arg); - -#endif diff --git a/zfs/lib/libdmu-ctl/include/sys/dmu_ctl_impl.h b/zfs/lib/libdmu-ctl/include/sys/dmu_ctl_impl.h deleted file mode 100644 index 6b4a564b3..000000000 --- a/zfs/lib/libdmu-ctl/include/sys/dmu_ctl_impl.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DMU_CTL_IMPL_H -#define _SYS_DMU_CTL_IMPL_H - -#include -#include -#include -#include -#include - -#define SOCKNAME "dmu_socket" - -#define DCTL_PROTOCOL_VER 1 -#define DCTL_MAGIC 0xdc71b1070c01dc71ll - -/* Message types */ -enum { - DCTL_IOCTL, - DCTL_IOCTL_REPLY, - DCTL_COPYIN, - DCTL_COPYINSTR, - DCTL_COPYOUT, - DCTL_FD_READ, - DCTL_FD_WRITE, - DCTL_GEN_REPLY /* generic reply */ -}; - -/* On-the-wire message */ -typedef struct dctl_cmd { - uint64_t dcmd_magic; - int8_t dcmd_version; - int8_t dcmd_msg; - uint8_t dcmd_pad[6]; - union { - struct dcmd_ioctl { - uint64_t arg; - int32_t cmd; - uint8_t pad[4]; - } dcmd_ioctl; - - struct dcmd_copy_req { - uint64_t ptr; - uint64_t size; - } dcmd_copy; - - struct dcmd_fd_req { - int64_t size; - int32_t fd; - uint8_t pad[4]; - } dcmd_fd_io; - - struct dcmd_reply { - uint64_t size; /* used by reply to DCTL_COPYINSTR, - DCTL_FD_READ and DCTL_FD_WRITE */ - int32_t rc; /* return code */ - uint8_t pad[4]; - } dcmd_reply; - } u; -} dctl_cmd_t; - -#define DCTL_CMD_HEADER_SIZE (sizeof(uint64_t) + sizeof(uint8_t)) - -/* - * The following definitions are only used by the server code. - */ - -#define LISTEN_BACKLOG 5 - -/* Worker thread data */ -typedef struct wthr_info { - list_node_t wthr_node; - pthread_t wthr_id; - boolean_t wthr_exit; /* termination flag */ - boolean_t wthr_free; -} wthr_info_t; - -/* Control socket data */ -typedef struct dctl_sock_info { - pthread_mutex_t dsi_mtx; - char *dsi_path; - struct sockaddr_un dsi_addr; - int dsi_fd; -} dctl_sock_info_t; - -typedef void *thr_func_t(void *); - -/* Thread pool data */ -typedef struct dctl_thr_info { - thr_func_t *dti_thr_func; - - pthread_mutex_t dti_mtx; /* protects the thread lists and dti_free */ - list_t dti_list; /* list of threads in the thread pool */ - list_t dti_join_list; /* list of threads that are waiting to be - joined */ - int dti_free; /* number of free worker threads */ - - int dti_min; - int dti_max_free; - - boolean_t dti_exit; /* global termination flag */ -} dctl_thr_info_t; - -/* Messaging functions functions */ -int dctl_read_msg(int fd, dctl_cmd_t *cmd); -int dctl_send_msg(int fd, dctl_cmd_t *cmd); - -int dctl_read_data(int fd, void *ptr, size_t size); -int dctl_send_data(int fd, const void *ptr, size_t size); - -/* Thread pool functions */ -int dctl_thr_pool_create(int min_thr, int max_free_thr, - thr_func_t *thr_func); -void dctl_thr_pool_stop(); - -void dctl_thr_join(); -void dctl_thr_die(wthr_info_t *thr); -void dctl_thr_rebalance(wthr_info_t *thr, boolean_t set_free); - -#endif diff --git a/zfs/lib/libnvpair/include/libnvpair.h b/zfs/lib/libnvpair/include/libnvpair.h index 9473cfe21..e655e0d40 100644 --- a/zfs/lib/libnvpair/include/libnvpair.h +++ b/zfs/lib/libnvpair/include/libnvpair.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,24 +19,27 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _LIBNVPAIR_H #define _LIBNVPAIR_H - +#pragma ident "%Z%%M% %I% %E% SMI" #include #include #include +#include #ifdef __cplusplus extern "C" { #endif void nvlist_print(FILE *, nvlist_t *); +int nvpair_value_match(nvpair_t *, int, char *, char **); +int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *, char **); #ifdef __cplusplus } diff --git a/zfs/lib/libnvpair/include/sys/nvpair.h b/zfs/lib/libnvpair/include/sys/nvpair.h index 005e751c3..9e768541f 100644 --- a/zfs/lib/libnvpair/include/sys/nvpair.h +++ b/zfs/lib/libnvpair/include/sys/nvpair.h @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_NVPAIR_H #define _SYS_NVPAIR_H - +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -67,7 +67,12 @@ typedef enum { DATA_TYPE_UINT8, DATA_TYPE_BOOLEAN_ARRAY, DATA_TYPE_INT8_ARRAY, +#if !defined(_KERNEL) + DATA_TYPE_UINT8_ARRAY, + DATA_TYPE_DOUBLE +#else DATA_TYPE_UINT8_ARRAY +#endif } data_type_t; typedef struct nvpair { @@ -188,6 +193,9 @@ int nvlist_add_uint64_array(nvlist_t *, const char *, uint64_t *, uint_t); int nvlist_add_string_array(nvlist_t *, const char *, char *const *, uint_t); int nvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint_t); int nvlist_add_hrtime(nvlist_t *, const char *, hrtime_t); +#if !defined(_KERNEL) +int nvlist_add_double(nvlist_t *, const char *, double); +#endif int nvlist_remove(nvlist_t *, const char *, data_type_t); int nvlist_remove_all(nvlist_t *, const char *); @@ -220,15 +228,21 @@ int nvlist_lookup_string_array(nvlist_t *, const char *, char ***, uint_t *); int nvlist_lookup_nvlist_array(nvlist_t *, const char *, nvlist_t ***, uint_t *); int nvlist_lookup_hrtime(nvlist_t *, const char *, hrtime_t *); -int nvlist_lookup_pairs(nvlist_t *nvl, int, ...); +int nvlist_lookup_pairs(nvlist_t *, int, ...); +#if !defined(_KERNEL) +int nvlist_lookup_double(nvlist_t *, const char *, double *); +#endif -int nvlist_lookup_nvpair(nvlist_t *nvl, const char *, nvpair_t **); -boolean_t nvlist_exists(nvlist_t *nvl, const char *); +int nvlist_lookup_nvpair(nvlist_t *, const char *, nvpair_t **); +int nvlist_lookup_nvpair_embedded_index(nvlist_t *, const char *, nvpair_t **, + int *, char **); +boolean_t nvlist_exists(nvlist_t *, const char *); /* processing nvpair */ -nvpair_t *nvlist_next_nvpair(nvlist_t *nvl, nvpair_t *); +nvpair_t *nvlist_next_nvpair(nvlist_t *, nvpair_t *); char *nvpair_name(nvpair_t *); data_type_t nvpair_type(nvpair_t *); +int nvpair_type_is_array(nvpair_t *); int nvpair_value_boolean_value(nvpair_t *, boolean_t *); int nvpair_value_byte(nvpair_t *, uchar_t *); int nvpair_value_int8(nvpair_t *, int8_t *); @@ -254,6 +268,9 @@ int nvpair_value_uint64_array(nvpair_t *, uint64_t **, uint_t *); int nvpair_value_string_array(nvpair_t *, char ***, uint_t *); int nvpair_value_nvlist_array(nvpair_t *, nvlist_t ***, uint_t *); int nvpair_value_hrtime(nvpair_t *, hrtime_t *); +#if !defined(_KERNEL) +int nvpair_value_double(nvpair_t *, double *); +#endif #ifdef __cplusplus } diff --git a/zfs/lib/libnvpair/include/sys/nvpair_impl.h b/zfs/lib/libnvpair/include/sys/nvpair_impl.h index b851ddd54..f12dbbfe6 100644 --- a/zfs/lib/libnvpair/include/sys/nvpair_impl.h +++ b/zfs/lib/libnvpair/include/sys/nvpair_impl.h @@ -27,7 +27,7 @@ #ifndef _NVPAIR_IMPL_H #define _NVPAIR_IMPL_H - +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { diff --git a/zfs/lib/libnvpair/libnvpair.c b/zfs/lib/libnvpair/libnvpair.c index bc6675425..0845cb08c 100644 --- a/zfs/lib/libnvpair/libnvpair.c +++ b/zfs/lib/libnvpair/libnvpair.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,14 +19,16 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include #include +#include +#include #include "libnvpair.h" /* @@ -137,6 +138,12 @@ nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth) (void) fprintf(fp, " 0x%llx", (u_longlong_t)val); break; } + case DATA_TYPE_DOUBLE: { + double val; + (void) nvpair_value_double(nvp, &val); + (void) fprintf(fp, " 0x%llf", val); + break; + } case DATA_TYPE_STRING: { char *val; (void) nvpair_value_string(nvp, &val); @@ -264,3 +271,348 @@ nvlist_print(FILE *fp, nvlist_t *nvl) { nvlist_print_with_indent(fp, nvl, 0); } + +/* + * Determine if string 'value' matches 'nvp' value. The 'value' string is + * converted, depending on the type of 'nvp', prior to match. For numeric + * types, a radix independent sscanf conversion of 'value' is used. If 'nvp' + * is an array type, 'ai' is the index into the array against which we are + * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass + * in a regex_t compilation of value in 'value_regex' to trigger regular + * expression string match instead of simple strcmp(). + * + * Return 1 on match, 0 on no-match, and -1 on error. If the error is + * related to value syntax error and 'ep' is non-NULL, *ep will point into + * the 'value' string at the location where the error exists. + * + * NOTE: It may be possible to move the non-regex_t version of this into + * common code used by library/kernel/boot. + */ +int +nvpair_value_match_regex(nvpair_t *nvp, int ai, + char *value, regex_t *value_regex, char **ep) +{ + char *evalue; + uint_t a_len; + int sr; + + if (ep) + *ep = NULL; + + if ((nvp == NULL) || (value == NULL)) + return (-1); /* error fail match - invalid args */ + + /* make sure array and index combination make sense */ + if ((nvpair_type_is_array(nvp) && (ai < 0)) || + (!nvpair_type_is_array(nvp) && (ai >= 0))) + return (-1); /* error fail match - bad index */ + + /* non-string values should be single 'chunk' */ + if ((nvpair_type(nvp) != DATA_TYPE_STRING) && + (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) { + value += strspn(value, " \t"); + evalue = value + strcspn(value, " \t"); + if (*evalue) { + if (ep) + *ep = evalue; + return (-1); /* error fail match - syntax */ + } + } + + sr = EOF; + switch (nvpair_type(nvp)) { + case DATA_TYPE_STRING: { + char *val; + + /* check string value for match */ + if (nvpair_value_string(nvp, &val) == 0) { + if (value_regex) { + if (regexec(value_regex, val, + (size_t)0, NULL, 0) == 0) + return (1); /* match */ + } else { + if (strcmp(value, val) == 0) + return (1); /* match */ + } + } + break; + } + case DATA_TYPE_STRING_ARRAY: { + char **val_array; + + /* check indexed string value of array for match */ + if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len)) { + if (value_regex) { + if (regexec(value_regex, val_array[ai], + (size_t)0, NULL, 0) == 0) + return (1); + } else { + if (strcmp(value, val_array[ai]) == 0) + return (1); + } + } + break; + } + case DATA_TYPE_BYTE: { + uchar_t val, val_arg; + + /* scanf uchar_t from value and check for match */ + sr = sscanf(value, "%c", &val_arg); + if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_BYTE_ARRAY: { + uchar_t *val_array, val_arg; + + + /* check indexed value of array for match */ + sr = sscanf(value, "%c", &val_arg); + if ((sr == 1) && + (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_INT8: { + int8_t val, val_arg; + + /* scanf int8_t from value and check for match */ + sr = sscanf(value, "%"SCNi8, &val_arg); + if ((sr == 1) && + (nvpair_value_int8(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_INT8_ARRAY: { + int8_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi8, &val_arg); + if ((sr == 1) && + (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_UINT8: { + uint8_t val, val_arg; + + /* scanf uint8_t from value and check for match */ + sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); + if ((sr == 1) && + (nvpair_value_uint8(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_UINT8_ARRAY: { + uint8_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); + if ((sr == 1) && + (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_INT16: { + int16_t val, val_arg; + + /* scanf int16_t from value and check for match */ + sr = sscanf(value, "%"SCNi16, &val_arg); + if ((sr == 1) && + (nvpair_value_int16(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_INT16_ARRAY: { + int16_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi16, &val_arg); + if ((sr == 1) && + (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_UINT16: { + uint16_t val, val_arg; + + /* scanf uint16_t from value and check for match */ + sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); + if ((sr == 1) && + (nvpair_value_uint16(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_UINT16_ARRAY: { + uint16_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); + if ((sr == 1) && + (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_INT32: { + int32_t val, val_arg; + + /* scanf int32_t from value and check for match */ + sr = sscanf(value, "%"SCNi32, &val_arg); + if ((sr == 1) && + (nvpair_value_int32(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_INT32_ARRAY: { + int32_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi32, &val_arg); + if ((sr == 1) && + (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_UINT32: { + uint32_t val, val_arg; + + /* scanf uint32_t from value and check for match */ + sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); + if ((sr == 1) && + (nvpair_value_uint32(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_UINT32_ARRAY: { + uint32_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); + if ((sr == 1) && + (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_INT64: { + int64_t val, val_arg; + + /* scanf int64_t from value and check for match */ + sr = sscanf(value, "%"SCNi64, &val_arg); + if ((sr == 1) && + (nvpair_value_int64(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_INT64_ARRAY: { + int64_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi64, &val_arg); + if ((sr == 1) && + (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_UINT64: { + uint64_t val_arg, val; + + /* scanf uint64_t from value and check for match */ + sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); + if ((sr == 1) && + (nvpair_value_uint64(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_UINT64_ARRAY: { + uint64_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); + if ((sr == 1) && + (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_BOOLEAN_VALUE: { + boolean_t val, val_arg; + + /* scanf boolean_t from value and check for match */ + sr = sscanf(value, "%"SCNi32, &val_arg); + if ((sr == 1) && + (nvpair_value_boolean_value(nvp, &val) == 0) && + (val == val_arg)) + return (1); + break; + } + case DATA_TYPE_BOOLEAN_ARRAY: { + boolean_t *val_array, val_arg; + + /* check indexed value of array for match */ + sr = sscanf(value, "%"SCNi32, &val_arg); + if ((sr == 1) && + (nvpair_value_boolean_array(nvp, + &val_array, &a_len) == 0) && + (ai < a_len) && + (val_array[ai] == val_arg)) + return (1); + break; + } + case DATA_TYPE_HRTIME: + case DATA_TYPE_NVLIST: + case DATA_TYPE_NVLIST_ARRAY: + case DATA_TYPE_BOOLEAN: + case DATA_TYPE_DOUBLE: + case DATA_TYPE_UNKNOWN: + default: + /* + * unknown/unsupported data type + */ + return (-1); /* error fail match */ + } + + /* + * check to see if sscanf failed conversion, return approximate + * pointer to problem + */ + if (sr != 1) { + if (ep) + *ep = value; + return (-1); /* error fail match - syntax */ + } + + return (0); /* fail match */ +} + +int +nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep) +{ + return (nvpair_value_match_regex(nvp, ai, value, NULL, ep)); +} diff --git a/zfs/lib/libnvpair/nvpair.c b/zfs/lib/libnvpair/nvpair.c index 9b8f51e30..77891bf77 100644 --- a/zfs/lib/libnvpair/nvpair.c +++ b/zfs/lib/libnvpair/nvpair.c @@ -20,11 +20,11 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -37,15 +37,19 @@ #if defined(_KERNEL) && !defined(_BOOT) #include +#include +#include #else #include +#include +#include #include #endif #ifndef offsetof -#define offsetof(s, m) ((size_t)(&(((s *)0)->m))) +#define offsetof(s, m) ((size_t)(&(((s *)0)->m))) #endif - +#define skip_whitespace(p) while ((*(p) == ' ') || (*(p) == '\t')) p++ /* * nvpair.c - Provides kernel & userland interfaces for manipulating @@ -204,7 +208,7 @@ nv_mem_free(nvpriv_t *nvp, void *buf, size_t size) static void nv_priv_init(nvpriv_t *priv, nv_alloc_t *nva, uint32_t stat) { - bzero(priv, sizeof (priv)); + bzero(priv, sizeof (nvpriv_t)); priv->nvp_nva = nva; priv->nvp_stat = stat; @@ -398,6 +402,9 @@ i_validate_type_nelem(data_type_t type, uint_t nelem) case DATA_TYPE_STRING: case DATA_TYPE_HRTIME: case DATA_TYPE_NVLIST: +#if !defined(_KERNEL) + case DATA_TYPE_DOUBLE: +#endif if (nelem != 1) return (EINVAL); break; @@ -736,6 +743,11 @@ i_get_value_size(data_type_t type, const void *data, uint_t nelem) case DATA_TYPE_UINT64: value_sz = sizeof (uint64_t); break; +#if !defined(_KERNEL) + case DATA_TYPE_DOUBLE: + value_sz = sizeof (double); + break; +#endif case DATA_TYPE_STRING: if (data == NULL) value_sz = 0; @@ -1020,6 +1032,14 @@ nvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t val) return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64, 1, &val)); } +#if !defined(_KERNEL) +int +nvlist_add_double(nvlist_t *nvl, const char *name, double val) +{ + return (nvlist_add_common(nvl, name, DATA_TYPE_DOUBLE, 1, &val)); +} +#endif + int nvlist_add_string(nvlist_t *nvl, const char *name, const char *val) { @@ -1154,6 +1174,27 @@ nvpair_type(nvpair_t *nvp) return (NVP_TYPE(nvp)); } +int +nvpair_type_is_array(nvpair_t *nvp) +{ + data_type_t type = NVP_TYPE(nvp); + + if ((type == DATA_TYPE_BYTE_ARRAY) || + (type == DATA_TYPE_UINT8_ARRAY) || + (type == DATA_TYPE_INT16_ARRAY) || + (type == DATA_TYPE_UINT16_ARRAY) || + (type == DATA_TYPE_INT32_ARRAY) || + (type == DATA_TYPE_UINT32_ARRAY) || + (type == DATA_TYPE_INT64_ARRAY) || + (type == DATA_TYPE_UINT64_ARRAY) || + (type == DATA_TYPE_BOOLEAN_ARRAY) || + (type == DATA_TYPE_STRING_ARRAY) || + (type == DATA_TYPE_NVLIST_ARRAY)) + return (1); + return (0); + +} + static int nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data) { @@ -1181,6 +1222,9 @@ nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data) case DATA_TYPE_INT64: case DATA_TYPE_UINT64: case DATA_TYPE_HRTIME: +#if !defined(_KERNEL) + case DATA_TYPE_DOUBLE: +#endif if (data == NULL) return (EINVAL); bcopy(NVP_VALUE(nvp), data, @@ -1317,6 +1361,14 @@ nvlist_lookup_uint64(nvlist_t *nvl, const char *name, uint64_t *val) return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64, NULL, val)); } +#if !defined(_KERNEL) +int +nvlist_lookup_double(nvlist_t *nvl, const char *name, double *val) +{ + return (nvlist_lookup_common(nvl, name, DATA_TYPE_DOUBLE, NULL, val)); +} +#endif + int nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val) { @@ -1451,6 +1503,9 @@ nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...) case DATA_TYPE_HRTIME: case DATA_TYPE_STRING: case DATA_TYPE_NVLIST: +#if !defined(_KERNEL) + case DATA_TYPE_DOUBLE: +#endif val = va_arg(ap, void *); ret = nvlist_lookup_common(nvl, name, type, NULL, val); break; @@ -1484,30 +1539,201 @@ nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...) return (ret); } +/* + * Find the 'name'ed nvpair in the nvlist 'nvl'. If 'name' found, the function + * returns zero and a pointer to the matching nvpair is returned in '*ret' + * (given 'ret' is non-NULL). If 'sep' is specified then 'name' will penitrate + * multiple levels of embedded nvlists, with 'sep' as the separator. As an + * example, if sep is '.', name might look like: "a" or "a.b" or "a.c[3]" or + * "a.d[3].e[1]". This matches the C syntax for array embed (for convience, + * code also supports "a.d[3]e[1]" syntax). + * + * If 'ip' is non-NULL and the last name component is an array, return the + * value of the "...[index]" array index in *ip. For an array reference that + * is not indexed, *ip will be returned as -1. If there is a syntax error in + * 'name', and 'ep' is non-NULL then *ep will be set to point to the location + * inside the 'name' string where the syntax error was detected. + */ +static int +nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep, + nvpair_t **ret, int *ip, char **ep) +{ + nvpair_t *nvp; + const char *np; + char *sepp; + char *idxp, *idxep; + nvlist_t **nva; + long idx; + int n; + + if (ip) + *ip = -1; /* not indexed */ + if (ep) + *ep = NULL; + + if ((nvl == NULL) || (name == NULL)) + return (EINVAL); + + /* step through components of name */ + for (np = name; np && *np; np = sepp) { + /* ensure unique names */ + if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME)) + return (ENOTSUP); + + /* skip white space */ + skip_whitespace(np); + if (*np == 0) + break; + + /* set 'sepp' to end of current component 'np' */ + if (sep) + sepp = strchr(np, sep); + else + sepp = NULL; + + /* find start of next "[ index ]..." */ + idxp = strchr(np, '['); + + /* if sepp comes first, set idxp to NULL */ + if (sepp && idxp && (sepp < idxp)) + idxp = NULL; + + /* + * At this point 'idxp' is set if there is an index + * expected for the current component. + */ + if (idxp) { + /* set 'n' to length of current 'np' name component */ + n = idxp++ - np; + + /* keep sepp up to date for *ep use as we advance */ + skip_whitespace(idxp); + sepp = idxp; + + /* determine the index value */ +#if defined(_KERNEL) && !defined(_BOOT) + if (ddi_strtol(idxp, &idxep, 0, &idx)) + goto fail; +#else + idx = strtol(idxp, &idxep, 0); +#endif + if (idxep == idxp) + goto fail; + + /* keep sepp up to date for *ep use as we advance */ + sepp = idxep; + + /* skip white space index value and check for ']' */ + skip_whitespace(sepp); + if (*sepp++ != ']') + goto fail; + + /* for embedded arrays, support C syntax: "a[1].b" */ + skip_whitespace(sepp); + if (sep && (*sepp == sep)) + sepp++; + } else if (sepp) { + n = sepp++ - np; + } else { + n = strlen(np); + } + + /* trim trailing whitespace by reducing length of 'np' */ + if (n == 0) + goto fail; + for (n--; (np[n] == ' ') || (np[n] == '\t'); n--) + ; + n++; + + /* skip whitespace, and set sepp to NULL if complete */ + if (sepp) { + skip_whitespace(sepp); + if (*sepp == 0) + sepp = NULL; + } + + /* + * At this point: + * o 'n' is the length of current 'np' component. + * o 'idxp' is set if there was an index, and value 'idx'. + * o 'sepp' is set to the beginning of the next component, + * and set to NULL if we have no more components. + * + * Search for nvpair with matching component name. + */ + for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL; + nvp = nvlist_next_nvpair(nvl, nvp)) { + + /* continue if no match on name */ + if (strncmp(np, nvpair_name(nvp), n) || + (strlen(nvpair_name(nvp)) != n)) + continue; + + /* if indexed, verify type is array oriented */ + if (idxp && !nvpair_type_is_array(nvp)) + goto fail; + + /* + * Full match found, return nvp and idx if this + * was the last component. + */ + if (sepp == NULL) { + if (ret) + *ret = nvp; + if (ip && idxp) + *ip = (int)idx; /* return index */ + return (0); /* found */ + } + + /* + * More components: current match must be + * of DATA_TYPE_NVLIST or DATA_TYPE_NVLIST_ARRAY + * to support going deeper. + */ + if (nvpair_type(nvp) == DATA_TYPE_NVLIST) { + nvl = EMBEDDED_NVL(nvp); + break; + } else if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY) { + (void) nvpair_value_nvlist_array(nvp, + &nva, (uint_t *)&n); + if ((n < 0) || (idx >= n)) + goto fail; + nvl = nva[idx]; + break; + } + + /* type does not support more levels */ + goto fail; + } + if (nvp == NULL) + goto fail; /* 'name' not found */ + + /* search for match of next component in embedded 'nvl' list */ + } + +fail: if (ep && sepp) + *ep = sepp; + return (EINVAL); +} + +/* + * Return pointer to nvpair with specified 'name'. + */ int nvlist_lookup_nvpair(nvlist_t *nvl, const char *name, nvpair_t **ret) { - nvpriv_t *priv; - nvpair_t *nvp; - i_nvp_t *curr; + return (nvlist_lookup_nvpair_ei_sep(nvl, name, 0, ret, NULL, NULL)); +} - if (name == NULL || nvl == NULL || - (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL) - return (EINVAL); - - if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME)) - return (ENOTSUP); - - for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) { - nvp = &curr->nvi_nvp; - - if (strcmp(name, NVP_NAME(nvp)) == 0) { - *ret = nvp; - return (0); - } - } - - return (ENOENT); +/* + * Determine if named nvpair exists in nvlist (use embedded separator of '.' + * and return array index). See nvlist_lookup_nvpair_ei_sep for more detailed + * description. + */ +int nvlist_lookup_nvpair_embedded_index(nvlist_t *nvl, + const char *name, nvpair_t **ret, int *ip, char **ep) +{ + return (nvlist_lookup_nvpair_ei_sep(nvl, name, '.', ret, ip, ep)); } boolean_t @@ -1591,6 +1817,14 @@ nvpair_value_uint64(nvpair_t *nvp, uint64_t *val) return (nvpair_value_common(nvp, DATA_TYPE_UINT64, NULL, val)); } +#if !defined(_KERNEL) +int +nvpair_value_double(nvpair_t *nvp, double *val) +{ + return (nvpair_value_common(nvp, DATA_TYPE_DOUBLE, NULL, val)); +} +#endif + int nvpair_value_string(nvpair_t *nvp, char **val) { @@ -2728,7 +2962,11 @@ nvs_xdr_nvp_op(nvstream_t *nvs, nvpair_t *nvp) */ ret = xdr_longlong_t(xdr, (void *)buf); break; - +#if !defined(_KERNEL) + case DATA_TYPE_DOUBLE: + ret = xdr_double(xdr, (void *)buf); + break; +#endif case DATA_TYPE_STRING: ret = xdr_string(xdr, &buf, buflen - 1); break; @@ -2834,6 +3072,9 @@ nvs_xdr_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size) case DATA_TYPE_INT64: case DATA_TYPE_UINT64: case DATA_TYPE_HRTIME: +#if !defined(_KERNEL) + case DATA_TYPE_DOUBLE: +#endif nvp_sz += 8; break; diff --git a/zfs/lib/libnvpair/nvpair_alloc_fixed.c b/zfs/lib/libnvpair/nvpair_alloc_fixed.c index 33e3c0d00..b1128eeb9 100644 --- a/zfs/lib/libnvpair/nvpair_alloc_fixed.c +++ b/zfs/lib/libnvpair/nvpair_alloc_fixed.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libnvpair/nvpair_alloc_system.c b/zfs/lib/libnvpair/nvpair_alloc_system.c index 0348fef55..e76557795 100644 --- a/zfs/lib/libnvpair/nvpair_alloc_system.c +++ b/zfs/lib/libnvpair/nvpair_alloc_system.c @@ -24,26 +24,25 @@ * Use is subject to license terms. */ +#pragma ident "%Z%%M% %I% %E% SMI" - +#include #include -#include -/*ARGSUSED*/ static void * nv_alloc_sys(nv_alloc_t *nva, size_t size) { - return (malloc(size)); + return (kmem_alloc(size, (int)(uintptr_t)nva->nva_arg)); } /*ARGSUSED*/ static void nv_free_sys(nv_alloc_t *nva, void *buf, size_t size) { - free(buf); + kmem_free(buf, size); } -const nv_alloc_ops_t system_ops_def = { +static const nv_alloc_ops_t system_ops = { NULL, /* nv_ao_init() */ NULL, /* nv_ao_fini() */ nv_alloc_sys, /* nv_ao_alloc() */ @@ -51,9 +50,15 @@ const nv_alloc_ops_t system_ops_def = { NULL /* nv_ao_reset() */ }; -nv_alloc_t nv_alloc_nosleep_def = { - &system_ops_def, - NULL +nv_alloc_t nv_alloc_sleep_def = { + &system_ops, + (void *)KM_SLEEP }; +nv_alloc_t nv_alloc_nosleep_def = { + &system_ops, + (void *)KM_NOSLEEP +}; + +nv_alloc_t *nv_alloc_sleep = &nv_alloc_sleep_def; nv_alloc_t *nv_alloc_nosleep = &nv_alloc_nosleep_def; diff --git a/zfs/lib/libport/include/fake_ioctl.h b/zfs/lib/libport/include/fake_ioctl.h deleted file mode 100644 index 74a612c5c..000000000 --- a/zfs/lib/libport/include/fake_ioctl.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PORT_FAKE_IOCTL_H -#define _PORT_FAKE_IOCTL_H - -static inline int real_ioctl(int fd, int request, void *arg) -{ - return ioctl(fd, request, arg); -} - -#ifdef WANT_FAKE_IOCTL - -#include -#define ioctl(fd,req,arg) dctlc_ioctl(fd,req,arg) - -#endif - -#endif /* _PORT_FAKE_IOCTL_H */ diff --git a/zfs/lib/libport/include/libdiskmgt.h b/zfs/lib/libport/include/libdiskmgt.h deleted file mode 100644 index c32637b62..000000000 --- a/zfs/lib/libport/include/libdiskmgt.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "zfs_config.h" - -#ifdef HAVE_LIBDISKMGT_H -#include_next -#else - -#ifndef _LIBDISKMGT_H -#define _LIBDISKMGT_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - - -/* - * Holds all the data regarding the device. - * Private to libdiskmgt. Must use dm_xxx functions to set/get data. - */ -typedef uint64_t dm_descriptor_t; - -typedef enum { - DM_WHO_MKFS = 0, - DM_WHO_ZPOOL, - DM_WHO_ZPOOL_FORCE, - DM_WHO_FORMAT, - DM_WHO_SWAP, - DM_WHO_DUMP, - DM_WHO_ZPOOL_SPARE -} dm_who_type_t; - -typedef enum { - DM_DRIVE = 0, - DM_CONTROLLER, - DM_MEDIA, - DM_SLICE, - DM_PARTITION, - DM_PATH, - DM_ALIAS, - DM_BUS -} dm_desc_type_t; - - -typedef enum { - DM_DT_UNKNOWN = 0, - DM_DT_FIXED, - DM_DT_ZIP, - DM_DT_JAZ, - DM_DT_FLOPPY, - DM_DT_MO_ERASABLE, - DM_DT_MO_WRITEONCE, - DM_DT_AS_MO, - DM_DT_CDROM, - DM_DT_CDR, - DM_DT_CDRW, - DM_DT_DVDROM, - DM_DT_DVDR, - DM_DT_DVDRAM, - DM_DT_DVDRW, - DM_DT_DDCDROM, - DM_DT_DDCDR, - DM_DT_DDCDRW -} dm_drive_type_t; - -typedef enum { - DM_MT_UNKNOWN = 0, - DM_MT_FIXED, - DM_MT_FLOPPY, - DM_MT_CDROM, - DM_MT_ZIP, - DM_MT_JAZ, - DM_MT_CDR, - DM_MT_CDRW, - DM_MT_DVDROM, - DM_MT_DVDR, - DM_MT_DVDRAM, - DM_MT_MO_ERASABLE, - DM_MT_MO_WRITEONCE, - DM_MT_AS_MO -} dm_media_type_t; - -#define DM_FILTER_END -1 - -/* drive stat name */ -typedef enum { - DM_DRV_STAT_PERFORMANCE = 0, - DM_DRV_STAT_DIAGNOSTIC, - DM_DRV_STAT_TEMPERATURE -} dm_drive_stat_t; - -/* slice stat name */ -typedef enum { - DM_SLICE_STAT_USE = 0 -} dm_slice_stat_t; - -/* attribute definitions */ - -/* drive */ -#define DM_DISK_UP 1 -#define DM_DISK_DOWN 0 - -#define DM_CLUSTERED "clustered" -#define DM_DRVTYPE "drvtype" -#define DM_FAILING "failing" -#define DM_LOADED "loaded" /* also in media */ -#define DM_NDNRERRS "ndevice_not_ready_errors" -#define DM_NBYTESREAD "nbytes_read" -#define DM_NBYTESWRITTEN "nbytes_written" -#define DM_NHARDERRS "nhard_errors" -#define DM_NILLREQERRS "nillegal_req_errors" -#define DM_NMEDIAERRS "nmedia_errors" -#define DM_NNODEVERRS "nno_dev_errors" -#define DM_NREADOPS "nread_ops" -#define DM_NRECOVERRS "nrecoverable_errors" -#define DM_NSOFTERRS "nsoft_errors" -#define DM_NTRANSERRS "ntransport_errors" -#define DM_NWRITEOPS "nwrite_ops" -#define DM_OPATH "opath" -#define DM_PRODUCT_ID "product_id" -#define DM_REMOVABLE "removable" /* also in media */ -#define DM_RPM "rpm" -#define DM_STATUS "status" -#define DM_SYNC_SPEED "sync_speed" -#define DM_TEMPERATURE "temperature" -#define DM_VENDOR_ID "vendor_id" -#define DM_WIDE "wide" /* also on controller */ -#define DM_WWN "wwn" - -/* bus */ -#define DM_BTYPE "btype" -#define DM_CLOCK "clock" /* also on controller */ -#define DM_PNAME "pname" - -/* controller */ -#define DM_FAST "fast" -#define DM_FAST20 "fast20" -#define DM_FAST40 "fast40" -#define DM_FAST80 "fast80" -#define DM_MULTIPLEX "multiplex" -#define DM_PATH_STATE "path_state" - -#define DM_CTYPE_ATA "ata" -#define DM_CTYPE_SCSI "scsi" -#define DM_CTYPE_FIBRE "fibre channel" -#define DM_CTYPE_USB "usb" -#define DM_CTYPE_UNKNOWN "unknown" - -/* media */ -#define DM_BLOCKSIZE "blocksize" -#define DM_FDISK "fdisk" -#define DM_MTYPE "mtype" -#define DM_NACTUALCYLINDERS "nactual_cylinders" -#define DM_NALTCYLINDERS "nalt_cylinders" -#define DM_NCYLINDERS "ncylinders" -#define DM_NHEADS "nheads" -#define DM_NPHYSCYLINDERS "nphys_cylinders" -#define DM_NSECTORS "nsectors" /* also in partition */ -#define DM_SIZE "size" /* also in slice */ -#define DM_NACCESSIBLE "naccessible" -#define DM_LABEL "label" - -/* partition */ -#define DM_BCYL "bcyl" -#define DM_BHEAD "bhead" -#define DM_BOOTID "bootid" -#define DM_BSECT "bsect" -#define DM_ECYL "ecyl" -#define DM_EHEAD "ehead" -#define DM_ESECT "esect" -#define DM_PTYPE "ptype" -#define DM_RELSECT "relsect" - -/* slice */ -#define DM_DEVICEID "deviceid" -#define DM_DEVT "devt" -#define DM_INDEX "index" -#define DM_EFI_NAME "name" -#define DM_MOUNTPOINT "mountpoint" -#define DM_LOCALNAME "localname" -#define DM_START "start" -#define DM_TAG "tag" -#define DM_FLAG "flag" -#define DM_EFI "efi" /* also on media */ -#define DM_USED_BY "used_by" -#define DM_USED_NAME "used_name" -#define DM_USE_MOUNT "mount" -#define DM_USE_SVM "svm" -#define DM_USE_LU "lu" -#define DM_USE_DUMP "dump" -#define DM_USE_VXVM "vxvm" -#define DM_USE_FS "fs" -#define DM_USE_VFSTAB "vfstab" -#define DM_USE_EXPORTED_ZPOOL "exported_zpool" -#define DM_USE_ACTIVE_ZPOOL "active_zpool" -#define DM_USE_SPARE_ZPOOL "spare_zpool" -#define DM_USE_L2CACHE_ZPOOL "l2cache_zpool" - -/* event */ -#define DM_EV_NAME "name" -#define DM_EV_DTYPE "edtype" -#define DM_EV_TYPE "evtype" -#define DM_EV_TADD "add" -#define DM_EV_TREMOVE "remove" -#define DM_EV_TCHANGE "change" - -/* findisks */ -#define DM_CTYPE "ctype" -#define DM_LUN "lun" -#define DM_TARGET "target" - -#define NOINUSE_SET getenv("NOINUSE_CHECK") != NULL - -void dm_free_descriptors(dm_descriptor_t *desc_list); -void dm_free_descriptor(dm_descriptor_t desc); -void dm_free_name(char *name); -void dm_free_swapentries(swaptbl_t *); - -dm_descriptor_t *dm_get_descriptors(dm_desc_type_t type, int filter[], - int *errp); -dm_descriptor_t *dm_get_associated_descriptors(dm_descriptor_t desc, - dm_desc_type_t type, int *errp); -dm_desc_type_t *dm_get_associated_types(dm_desc_type_t type); -dm_descriptor_t dm_get_descriptor_by_name(dm_desc_type_t desc_type, - char *name, int *errp); -char *dm_get_name(dm_descriptor_t desc, int *errp); -dm_desc_type_t dm_get_type(dm_descriptor_t desc); -nvlist_t *dm_get_attributes(dm_descriptor_t desc, int *errp); -nvlist_t *dm_get_stats(dm_descriptor_t desc, int stat_type, - int *errp); -void dm_init_event_queue(void(*callback)(nvlist_t *, int), - int *errp); -nvlist_t *dm_get_event(int *errp); -void dm_get_slices(char *drive, dm_descriptor_t **slices, - int *errp); -void dm_get_slice_stats(char *slice, nvlist_t **dev_stats, - int *errp); -int dm_get_swapentries(swaptbl_t **, int *); -void dm_get_usage_string(char *who, char *data, char **msg); -int dm_inuse(char *dev_name, char **msg, dm_who_type_t who, - int *errp); -int dm_inuse_swap(const char *dev_name, int *errp); -int dm_isoverlapping(char *dev_name, char **msg, int *errp); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBDISKMGT_H */ -#endif /* HAVE_LIBDISKMGT_H */ diff --git a/zfs/lib/libport/include/libshare.h b/zfs/lib/libport/include/libshare.h deleted file mode 100644 index e7a2840f7..000000000 --- a/zfs/lib/libport/include/libshare.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * basic API declarations for share management - */ - -#include "zfs_config.h" - -#ifdef HAVE_LIBSHARE -#include_next -#else - -#ifndef _LIBSHARE_H -#define _LIBSHARE_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* - * Basic datatypes for most functions - */ -typedef void *sa_group_t; -typedef void *sa_share_t; -typedef void *sa_property_t; -typedef void *sa_optionset_t; -typedef void *sa_security_t; -typedef void *sa_protocol_properties_t; -typedef void *sa_resource_t; - -typedef void *sa_handle_t; /* opaque handle to access core functions */ - -/* - * defined error values - */ - -#define SA_OK 0 -#define SA_NO_SUCH_PATH 1 /* provided path doesn't exist */ -#define SA_NO_MEMORY 2 /* no memory for data structures */ -#define SA_DUPLICATE_NAME 3 /* object name is already in use */ -#define SA_BAD_PATH 4 /* not a full path */ -#define SA_NO_SUCH_GROUP 5 /* group is not defined */ -#define SA_CONFIG_ERR 6 /* system configuration error */ -#define SA_SYSTEM_ERR 7 /* system error, use errno */ -#define SA_SYNTAX_ERR 8 /* syntax error on command line */ -#define SA_NO_PERMISSION 9 /* no permission for operation */ -#define SA_BUSY 10 /* resource is busy */ -#define SA_NO_SUCH_PROP 11 /* property doesn't exist */ -#define SA_INVALID_NAME 12 /* name of object is invalid */ -#define SA_INVALID_PROTOCOL 13 /* specified protocol not valid */ -#define SA_NOT_ALLOWED 14 /* operation not allowed */ -#define SA_BAD_VALUE 15 /* bad value for property */ -#define SA_INVALID_SECURITY 16 /* invalid security type */ -#define SA_NO_SUCH_SECURITY 17 /* security set not found */ -#define SA_VALUE_CONFLICT 18 /* property value conflict */ -#define SA_NOT_IMPLEMENTED 19 /* plugin interface not implemented */ -#define SA_INVALID_PATH 20 /* path is sub-dir of existing share */ -#define SA_NOT_SUPPORTED 21 /* operation not supported for proto */ -#define SA_PROP_SHARE_ONLY 22 /* property valid on share only */ -#define SA_NOT_SHARED 23 /* path is not shared */ -#define SA_NO_SUCH_RESOURCE 24 /* resource not found */ -#define SA_RESOURCE_REQUIRED 25 /* resource name is required */ -#define SA_MULTIPLE_ERROR 26 /* multiple protocols reported error */ -#define SA_PATH_IS_SUBDIR 27 /* check_path found path is subdir */ -#define SA_PATH_IS_PARENTDIR 28 /* check_path found path is parent */ -#define SA_NO_SECTION 29 /* protocol requires section info */ -#define SA_NO_SUCH_SECTION 30 /* no section found */ -#define SA_NO_PROPERTIES 31 /* no properties found */ -#define SA_PASSWORD_ENC 32 /* passwords must be encrypted */ - -/* API Initialization */ -#define SA_INIT_SHARE_API 0x0001 /* init share specific interface */ -#define SA_INIT_CONTROL_API 0x0002 /* init control specific interface */ - -/* not part of API returns */ -#define SA_LEGACY_ERR 32 /* share/unshare error return */ - -/* - * other defined values - */ - -#define SA_MAX_NAME_LEN 100 /* must fit service instance name */ -#define SA_MAX_RESOURCE_NAME 255 /* Maximum length of resource name */ - -/* Used in calls to sa_add_share() and sa_add_resource() */ -#define SA_SHARE_TRANSIENT 0 /* shared but not across reboot */ -#define SA_SHARE_LEGACY 1 /* share is in dfstab only */ -#define SA_SHARE_PERMANENT 2 /* share goes to repository */ - -/* sa_check_path() related */ -#define SA_CHECK_NORMAL 0 /* only check against active shares */ -#define SA_CHECK_STRICT 1 /* check against all shares */ - -/* RBAC related */ -#define SA_RBAC_MANAGE "solaris.smf.manage.shares" -#define SA_RBAC_VALUE "solaris.smf.value.shares" - -/* - * Feature set bit definitions - */ - -#define SA_FEATURE_NONE 0x0000 /* no feature flags set */ -#define SA_FEATURE_RESOURCE 0x0001 /* resource names are required */ -#define SA_FEATURE_DFSTAB 0x0002 /* need to manage in dfstab */ -#define SA_FEATURE_ALLOWSUBDIRS 0x0004 /* allow subdirs to be shared */ -#define SA_FEATURE_ALLOWPARDIRS 0x0008 /* allow parent dirs to be shared */ -#define SA_FEATURE_HAS_SECTIONS 0x0010 /* protocol supports sections */ -#define SA_FEATURE_ADD_PROPERTIES 0x0020 /* can add properties */ -#define SA_FEATURE_SERVER 0x0040 /* protocol supports server mode */ - -/* - * legacy files - */ - -#define SA_LEGACY_DFSTAB "/etc/dfs/dfstab" -#define SA_LEGACY_SHARETAB "/etc/dfs/sharetab" - -/* - * SMF related - */ - -#define SA_SVC_FMRI_BASE "svc:/network/shares/group" - -/* initialization */ -extern sa_handle_t sa_init(int); -extern void sa_fini(sa_handle_t); -extern int sa_update_config(sa_handle_t); -extern char *sa_errorstr(int); - -/* protocol names */ -extern int sa_get_protocols(char ***); -extern int sa_valid_protocol(char *); - -/* group control (create, remove, etc) */ -extern sa_group_t sa_create_group(sa_handle_t, char *, int *); -extern int sa_remove_group(sa_group_t); -extern sa_group_t sa_get_group(sa_handle_t, char *); -extern sa_group_t sa_get_next_group(sa_group_t); -extern char *sa_get_group_attr(sa_group_t, char *); -extern int sa_set_group_attr(sa_group_t, char *, char *); -extern sa_group_t sa_get_sub_group(sa_group_t); -extern int sa_valid_group_name(char *); - -/* share control */ -extern sa_share_t sa_add_share(sa_group_t, char *, int, int *); -extern int sa_check_path(sa_group_t, char *, int); -extern int sa_move_share(sa_group_t, sa_share_t); -extern int sa_remove_share(sa_share_t); -extern sa_share_t sa_get_share(sa_group_t, char *); -extern sa_share_t sa_find_share(sa_handle_t, char *); -extern sa_share_t sa_get_next_share(sa_share_t); -extern char *sa_get_share_attr(sa_share_t, char *); -extern char *sa_get_share_description(sa_share_t); -extern sa_group_t sa_get_parent_group(sa_share_t); -extern int sa_set_share_attr(sa_share_t, char *, char *); -extern int sa_set_share_description(sa_share_t, char *); -extern int sa_enable_share(sa_group_t, char *); -extern int sa_disable_share(sa_share_t, char *); -extern int sa_is_share(void *); - -/* resource name related */ -extern sa_resource_t sa_find_resource(sa_handle_t, char *); -extern sa_resource_t sa_get_resource(sa_group_t, char *); -extern sa_resource_t sa_get_next_resource(sa_resource_t); -extern sa_share_t sa_get_resource_parent(sa_resource_t); -extern sa_resource_t sa_get_share_resource(sa_share_t, char *); -extern sa_resource_t sa_add_resource(sa_share_t, char *, int, int *); -extern int sa_remove_resource(sa_resource_t); -extern char *sa_get_resource_attr(sa_resource_t, char *); -extern int sa_set_resource_attr(sa_resource_t, char *, char *); -extern int sa_set_resource_description(sa_resource_t, char *); -extern char *sa_get_resource_description(sa_resource_t); -extern int sa_enable_resource(sa_resource_t, char *); -extern int sa_disable_resource(sa_resource_t, char *); -extern int sa_rename_resource(sa_resource_t, char *); -extern void sa_fix_resource_name(char *); - -/* data structure free calls */ -extern void sa_free_attr_string(char *); -extern void sa_free_share_description(char *); - -/* optionset control */ -extern sa_optionset_t sa_get_optionset(sa_group_t, char *); -extern sa_optionset_t sa_get_next_optionset(sa_group_t); -extern char *sa_get_optionset_attr(sa_optionset_t, char *); -extern void sa_set_optionset_attr(sa_optionset_t, char *, char *); -extern sa_optionset_t sa_create_optionset(sa_group_t, char *); -extern int sa_destroy_optionset(sa_optionset_t); -extern sa_optionset_t sa_get_derived_optionset(void *, char *, int); -extern void sa_free_derived_optionset(sa_optionset_t); - -/* property functions */ -extern sa_property_t sa_get_property(sa_optionset_t, char *); -extern sa_property_t sa_get_next_property(sa_group_t); -extern char *sa_get_property_attr(sa_property_t, char *); -extern sa_property_t sa_create_section(char *, char *); -extern void sa_set_section_attr(sa_property_t, char *, char *); -extern sa_property_t sa_create_property(char *, char *); -extern int sa_add_property(void *, sa_property_t); -extern int sa_update_property(sa_property_t, char *); -extern int sa_remove_property(sa_property_t); -extern int sa_commit_properties(sa_optionset_t, int); -extern int sa_valid_property(void *, char *, sa_property_t); -extern int sa_is_persistent(void *); - -/* security control */ -extern sa_security_t sa_get_security(sa_group_t, char *, char *); -extern sa_security_t sa_get_next_security(sa_security_t); -extern char *sa_get_security_attr(sa_optionset_t, char *); -extern sa_security_t sa_create_security(sa_group_t, char *, char *); -extern int sa_destroy_security(sa_security_t); -extern void sa_set_security_attr(sa_security_t, char *, char *); -extern sa_optionset_t sa_get_all_security_types(void *, char *, int); -extern sa_security_t sa_get_derived_security(void *, char *, char *, int); -extern void sa_free_derived_security(sa_security_t); - -/* protocol specific interfaces */ -extern int sa_parse_legacy_options(sa_group_t, char *, char *); -extern char *sa_proto_legacy_format(char *, sa_group_t, int); -extern int sa_is_security(char *, char *); -extern sa_protocol_properties_t sa_proto_get_properties(char *); -extern uint64_t sa_proto_get_featureset(char *); -extern sa_property_t sa_get_protocol_section(sa_protocol_properties_t, char *); -extern sa_property_t sa_get_next_protocol_section(sa_property_t, char *); -extern sa_property_t sa_get_protocol_property(sa_protocol_properties_t, char *); -extern sa_property_t sa_get_next_protocol_property(sa_property_t, char *); -extern int sa_set_protocol_property(sa_property_t, char *, char *); -extern char *sa_get_protocol_status(char *); -extern void sa_format_free(char *); -extern sa_protocol_properties_t sa_create_protocol_properties(char *); -extern int sa_add_protocol_property(sa_protocol_properties_t, sa_property_t); -extern int sa_proto_valid_prop(char *, sa_property_t, sa_optionset_t); -extern int sa_proto_valid_space(char *, char *); -extern char *sa_proto_space_alias(char *, char *); -extern int sa_proto_get_transients(sa_handle_t, char *); -extern int sa_proto_notify_resource(sa_resource_t, char *); -extern int sa_proto_change_notify(sa_share_t, char *); -extern int sa_proto_delete_section(char *, char *); - -/* handle legacy (dfstab/sharetab) files */ -extern int sa_delete_legacy(sa_share_t, char *); -extern int sa_update_legacy(sa_share_t, char *); -extern int sa_update_sharetab(sa_share_t, char *); -extern int sa_delete_sharetab(sa_handle_t, char *, char *); - -/* ZFS functions */ -extern int sa_zfs_is_shared(sa_handle_t, char *); -extern int sa_group_is_zfs(sa_group_t); -extern int sa_path_is_zfs(char *); - -/* SA Handle specific functions */ -extern sa_handle_t sa_find_group_handle(sa_group_t); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBSHARE_H */ -#endif /* HAVE_LIBSHARE */ diff --git a/zfs/lib/libport/include/mntent.h b/zfs/lib/libport/include/mntent.h deleted file mode 100644 index 02f2fc6b9..000000000 --- a/zfs/lib/libport/include/mntent.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_MNTENT_H -#define _PORT_MNTENT_H - -/* For HAVE_SETMNTENT */ -#include "zfs_config.h" - -#endif diff --git a/zfs/lib/libport/include/stdlib.h b/zfs/lib/libport/include/stdlib.h deleted file mode 100644 index db3498ca0..000000000 --- a/zfs/lib/libport/include/stdlib.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_STDLIB_H -#define _PORT_STDLIB_H - -#include "zfs_config.h" - -#ifndef HAVE_GETEXECNAME -extern const char *getexecname(); -#endif - -#endif diff --git a/zfs/lib/libport/include/string.h b/zfs/lib/libport/include/string.h deleted file mode 100644 index f99c622c7..000000000 --- a/zfs/lib/libport/include/string.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_STRING_H -#define _PORT_STRING_H - -#include "zfs_config.h" - -#ifndef HAVE_STRLCPY -extern size_t strlcpy(char *dst, const char *src, size_t len); -#endif - -#ifndef HAVE_STRLCAT -extern size_t strlcat(char *, const char *, size_t); -#endif - -#ifndef HAVE_STRNLEN -extern size_t strnlen(const char *src, size_t maxlen); -#endif - -#endif diff --git a/zfs/lib/libport/include/strings.h b/zfs/lib/libport/include/strings.h deleted file mode 100644 index 7ba85ffde..000000000 --- a/zfs/lib/libport/include/strings.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_STRINGS_H -#define _PORT_STRINGS_H - -#include "zfs_config.h" - -#ifndef HAVE_STRCMP_IN_STRINGS_H -#include -#endif - -#endif diff --git a/zfs/lib/libport/include/stropts.h b/zfs/lib/libport/include/stropts.h deleted file mode 100644 index 448df8046..000000000 --- a/zfs/lib/libport/include/stropts.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_STROPTS_H -#define _PORT_STROPTS_H - -#include "zfs_config.h" - -#ifdef HAVE_IOCTL_IN_STROPTS_H -#include -#endif - -#endif /* _PORT_STROPTS_H */ diff --git a/zfs/lib/libport/include/sys/byteorder.h b/zfs/lib/libport/include/sys/byteorder.h deleted file mode 100644 index 5e356297a..000000000 --- a/zfs/lib/libport/include/sys/byteorder.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "zfs_config.h" - -#ifdef HAVE_SYS_BYTEORDER_H -#include_next -#endif diff --git a/zfs/lib/libport/include/sys/debug.h b/zfs/lib/libport/include/sys/debug.h deleted file mode 100644 index ca912e6f6..000000000 --- a/zfs/lib/libport/include/sys/debug.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PORT_SYS_DEBUG_H -#define _PORT_SYS_DEBUG_H - -#include - -/* This definition is copied from assert.h. */ -#if defined(__STDC__) -#if __STDC_VERSION__ - 0 >= 199901L -#define zp_verify(EX) (void)((EX) || \ - (__assert_c99(#EX, __FILE__, __LINE__, __func__), 0)) -#else -#define zp_verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0)) -#endif /* __STDC_VERSION__ - 0 >= 199901L */ -#else -#define zp_verify(EX) (void)((EX) || (_assert("EX", __FILE__, __LINE__), 0)) -#endif /* __STDC__ */ - -#define VERIFY(EX) zp_verify(EX) -#define ASSERT(EX) assert(EX) - -#endif diff --git a/zfs/lib/libport/include/sys/efi_partition.h b/zfs/lib/libport/include/sys/efi_partition.h deleted file mode 100644 index 368a817e4..000000000 --- a/zfs/lib/libport/include/sys/efi_partition.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "zfs_config.h" - -#ifdef HAVE_LIBEFI - -#include_next - -#ifndef EFI_MIN_RESV_SIZE -#define EFI_MIN_RESV_SIZE (16 * 1024) -#endif - -#endif diff --git a/zfs/lib/libport/include/sys/ioctl.h b/zfs/lib/libport/include/sys/ioctl.h deleted file mode 100644 index 802569da7..000000000 --- a/zfs/lib/libport/include/sys/ioctl.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_SYS_IOCTL_H -#define _PORT_SYS_IOCTL_H - -#include "zfs_config.h" - -#ifdef HAVE_IOCTL_IN_SYS_IOCTL_H -#include -#endif - -#endif /* _PORT_SYS_IOCTL_H */ diff --git a/zfs/lib/libport/include/sys/isa_defs.h b/zfs/lib/libport/include/sys/isa_defs.h deleted file mode 100644 index c5ddce3fd..000000000 --- a/zfs/lib/libport/include/sys/isa_defs.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "zfs_config.h" - -#ifdef HAVE_SYS_ISA_DEFS_H -#include_next -#endif diff --git a/zfs/lib/libport/include/sys/policy.h b/zfs/lib/libport/include/sys/policy.h deleted file mode 100644 index b8b9b63c9..000000000 --- a/zfs/lib/libport/include/sys/policy.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PORT_SYS_POLICY_H -#define _PORT_SYS_POLICY_H - -#ifdef WANT_KERNEL_EMUL - -#define secpolicy_fs_unmount(c,vfs) (0) -#define secpolicy_nfs(c) (0) -#define secpolicy_sys_config(c,co) (0) -#define secpolicy_zfs(c) (0) -#define secpolicy_zinject(c) (0) - -#endif /* WANT_KERNEL_EMUL */ - -#endif /* _PORT_SYS_POLICY_H */ diff --git a/zfs/lib/libport/include/sys/socket.h b/zfs/lib/libport/include/sys/socket.h deleted file mode 100644 index 0c1ee623f..000000000 --- a/zfs/lib/libport/include/sys/socket.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_SYS_SOCKET_H -#define _PORT_SYS_SOCKET_H - -/* Solaris doesn't have MSG_NOSIGNAL */ -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 -#endif - -#endif diff --git a/zfs/lib/libport/include/sys/swap.h b/zfs/lib/libport/include/sys/swap.h deleted file mode 100644 index a0c1bfd5d..000000000 --- a/zfs/lib/libport/include/sys/swap.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PORT_SYS_SWAP_H -#define _PORT_SYS_SWAP_H - -typedef int swaptbl_t; - -#endif diff --git a/zfs/lib/libport/include/sys/systeminfo.h b/zfs/lib/libport/include/sys/systeminfo.h deleted file mode 100644 index abee49a90..000000000 --- a/zfs/lib/libport/include/sys/systeminfo.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "zfs_config.h" - -#ifdef HAVE_SYS_SYSTEMINFO_H -#include_next -#endif - -#ifndef _PORT_SYS_SYSTEMINFO_H -#define _PORT_SYS_SYSTEMINFO_H - -#ifndef HAVE_SYSINFO_IN_SYSTEMINFO_H -#define sysinfo(cmd,buf,cnt) (-1) -#endif - -#endif diff --git a/zfs/lib/libport/include/sys/systm.h b/zfs/lib/libport/include/sys/systm.h deleted file mode 100644 index 2c157e2a6..000000000 --- a/zfs/lib/libport/include/sys/systm.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PORT_SYS_SYSTM_H -#define _PORT_SYS_SYSTM_H - -#ifdef WANT_KERNEL_EMUL - -#include - -#define copyinstr(from,to,max,len) dctls_copyinstr(from,to,max,len) -#define xcopyin(src,dest,size) dctls_copyin(src,dest,size) -#define xcopyout(src,dest,size) dctls_copyout(src,dest,size) - -#endif /* WANT_KERNEL_EMUL */ - -#endif /* _PORT_SYS_SYSM_H */ diff --git a/zfs/lib/libport/include/sys/time.h b/zfs/lib/libport/include/sys/time.h deleted file mode 100644 index 2400629de..000000000 --- a/zfs/lib/libport/include/sys/time.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef NANOSEC -#define NANOSEC 1000000000 -#endif diff --git a/zfs/lib/libport/include/sys/types.h b/zfs/lib/libport/include/sys/types.h deleted file mode 100644 index 22671a410..000000000 --- a/zfs/lib/libport/include/sys/types.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_SYS_TYPES_H -#define _PORT_SYS_TYPES_H - -#include "zfs_config.h" - -#ifndef HAVE_INTTYPES -#include - -typedef enum boolean { B_FALSE, B_TRUE } boolean_t; - -typedef unsigned char uchar_t; -typedef unsigned short ushort_t; -typedef unsigned int uint_t; -typedef unsigned long ulong_t; - -typedef long long longlong_t; -typedef unsigned long long u_longlong_t; - -#endif /* HAVE_INTTYPES */ - -#endif diff --git a/zfs/lib/libport/include/sys/u8_textprep.h b/zfs/lib/libport/include/sys/u8_textprep.h deleted file mode 100644 index 041ef611c..000000000 --- a/zfs/lib/libport/include/sys/u8_textprep.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include "zfs_config.h" - -#ifdef HAVE_UNICODE -#include_next -#else - -#ifndef _SYS_U8_TEXTPREP_H -#define _SYS_U8_TEXTPREP_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Unicode encoding conversion functions and their macros. - */ -#define UCONV_IN_BIG_ENDIAN 0x0001 -#define UCONV_OUT_BIG_ENDIAN 0x0002 -#define UCONV_IN_SYSTEM_ENDIAN 0x0004 -#define UCONV_OUT_SYSTEM_ENDIAN 0x0008 -#define UCONV_IN_LITTLE_ENDIAN 0x0010 -#define UCONV_OUT_LITTLE_ENDIAN 0x0020 -#define UCONV_IGNORE_NULL 0x0040 -#define UCONV_IN_ACCEPT_BOM 0x0080 -#define UCONV_OUT_EMIT_BOM 0x0100 - -extern int uconv_u16tou32(const uint16_t *, size_t *, uint32_t *, size_t *, - int); -extern int uconv_u16tou8(const uint16_t *, size_t *, uchar_t *, size_t *, int); -extern int uconv_u32tou16(const uint32_t *, size_t *, uint16_t *, size_t *, - int); -extern int uconv_u32tou8(const uint32_t *, size_t *, uchar_t *, size_t *, int); -extern int uconv_u8tou16(const uchar_t *, size_t *, uint16_t *, size_t *, int); -extern int uconv_u8tou32(const uchar_t *, size_t *, uint32_t *, size_t *, int); - -/* - * UTF-8 text preparation functions and their macros. - * - * Among the macros defined, U8_CANON_DECOMP, U8_COMPAT_DECOMP, and - * U8_CANON_COMP are not public interfaces and must not be used directly - * at the flag input argument. - */ -#define U8_STRCMP_CS (0x00000001) -#define U8_STRCMP_CI_UPPER (0x00000002) -#define U8_STRCMP_CI_LOWER (0x00000004) - -#define U8_CANON_DECOMP (0x00000010) -#define U8_COMPAT_DECOMP (0x00000020) -#define U8_CANON_COMP (0x00000040) - -#define U8_STRCMP_NFD (U8_CANON_DECOMP) -#define U8_STRCMP_NFC (U8_CANON_DECOMP | U8_CANON_COMP) -#define U8_STRCMP_NFKD (U8_COMPAT_DECOMP) -#define U8_STRCMP_NFKC (U8_COMPAT_DECOMP | U8_CANON_COMP) - -#define U8_TEXTPREP_TOUPPER (U8_STRCMP_CI_UPPER) -#define U8_TEXTPREP_TOLOWER (U8_STRCMP_CI_LOWER) - -#define U8_TEXTPREP_NFD (U8_STRCMP_NFD) -#define U8_TEXTPREP_NFC (U8_STRCMP_NFC) -#define U8_TEXTPREP_NFKD (U8_STRCMP_NFKD) -#define U8_TEXTPREP_NFKC (U8_STRCMP_NFKC) - -#define U8_TEXTPREP_IGNORE_NULL (0x00010000) -#define U8_TEXTPREP_IGNORE_INVALID (0x00020000) -#define U8_TEXTPREP_NOWAIT (0x00040000) - -#define U8_UNICODE_320 (0) -#define U8_UNICODE_500 (1) -#define U8_UNICODE_LATEST (U8_UNICODE_500) - -#define U8_VALIDATE_ENTIRE (0x00100000) -#define U8_VALIDATE_CHECK_ADDITIONAL (0x00200000) -#define U8_VALIDATE_UCS2_RANGE (0x00400000) - -#define U8_ILLEGAL_CHAR (-1) -#define U8_OUT_OF_RANGE_CHAR (-2) - -extern int u8_validate(char *, size_t, char **, int, int *); -extern int u8_strcmp(const char *, const char *, size_t, int, size_t, int *); -extern size_t u8_textprep_str(char *, size_t *, char *, size_t *, int, size_t, - int *); - -#ifdef __cplusplus -} -#endif - -#endif /* HAVE_UNICODE */ - -#endif /* _SYS_U8_TEXTPREP_H */ diff --git a/zfs/lib/libport/include/sys/u8_textprep_data.h b/zfs/lib/libport/include/sys/u8_textprep_data.h deleted file mode 100644 index 5980bc543..000000000 --- a/zfs/lib/libport/include/sys/u8_textprep_data.h +++ /dev/null @@ -1,35382 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * COPYRIGHT AND PERMISSION NOTICE - * - * Copyright (c) 1991-2006 Unicode, Inc. All rights reserved. Distributed under - * the Terms of Use in http://www.unicode.org/copyright.html. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of the Unicode data files and any associated documentation (the - * "Data Files") or Unicode software and any associated documentation (the - * "Software") to deal in the Data Files or Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, and/or sell copies of the Data Files or Software, and - * to permit persons to whom the Data Files or Software are furnished to do so, - * provided that (a) the above copyright notice(s) and this permission notice - * appear with all copies of the Data Files or Software, (b) both the above - * copyright notice(s) and this permission notice appear in associated - * documentation, and (c) there is clear notice in each modified Data File or - * in the Software as well as in the documentation associated with the Data - * File(s) or Software that the data or software has been modified. - * - * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY - * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR - * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THE DATA FILES OR SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall not - * be used in advertising or otherwise to promote the sale, use or other - * dealings in these Data Files or Software without prior written authorization - * of the copyright holder. - * - * Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be - * registered in some jurisdictions. All other trademarks and registered - * trademarks mentioned herein are the property of their respective owners. - */ -/* - * This file has been modified by Sun Microsystems, Inc. - */ - -#include "zfs_config.h" - -#ifdef HAVE_UNICODE -#include_next -#else - -#ifndef _SYS_U8_TEXTPREP_DATA_H -#define _SYS_U8_TEXTPREP_DATA_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * To get to the combining class data, composition mappings, decomposition - * mappings, and case conversion mappings of Unicode, the data structures - * formulated and their meanings are like the following: - * - * Each UTF-8 character is seen as a 4-byte entity so that U+0061 (or 0x61 in - * UTF-8) would be seen as 0x00 0x00 0x00 0x61. Similarly, U+1D15E would be - * 0xF0 0x9D 0x85 0x9E in UTF-8. - * - * The first byte (MSB) value is an index to the b1_tbl, such as - * u8_common_b1_tbl and u8_composition_b1_tbl tables. A b1_tbl has - * indices to b2_tbl tables that have indices to b3_tbl. Each b3_tbl has - * either indices to b4_tbl or indices to b4_tbl and base values for - * displacement calculations later by using the u8_displacement_t type at - * below. Each b4_tbl table then has indices to the final tables. - * - * As an example, if we have a character with code value of U+1D15E which is - * 0xF0 0x9D 0x85 0x9E in UTF-8, the target decomposition character bytes - * that will be mapped by the mapping procedure would be the ones between - * the start_index and the end_index computed as like the following: - * - * b2_tbl_id = u8_common_b1_tbl[0][0xF0]; - * b3_tbl_id = u8_decomp_b2_tbl[0][b2_tbl_id][0x9D]; - * b4_tbl_id = u8_decomp_b3_tbl[0][b3_tbl_id][0x85].tbl_id; - * b4_base = u8_decomp_b3_tbl[0][b3_tbl_id][0x85].base; - * if (b4_tbl_id >= 0x8000) { - * b4_tbl_id -= 0x8000; - * start_index = u8_decomp_b4_16bit_tbl[0][b4_tbl_id][0x9E]; - * end_index = u8_decomp_b4_16bit_tbl[0][b4_tbl_id][0x9E + 1]; - * } else { - * start_index = u8_decomp_b4_tbl[0][b4_tbl_id][0x9E]; - * end_index = u8_decomp_b4_tbl[0][b4_tbl_id][0x9E + 1]; - * } - * - * The start_index and the end_index can be used to retrieve the bytes - * possibly of multiple UTF-8 characters from the final tables. - * - * The "[0]" at the above indicates this is for Unicode Version 3.2.0 data - * as of today. Consequently, the "[1]" indicates another Unicode version - * data and it is Unicode 5.0.0 as of today. - * - * The mapping procedures and the data structures are more or less similar or - * alike among different mappings. You might want to read the u8_textprep.c - * for specific details. - * - * The tool programs created and used to generate the tables in this file are - * saved at PSARC/2007/149/materials/ as tools.tar.gz file. - */ - -/* The following is a component type for the b4_tbl vectors. */ -typedef struct { - uint16_t tbl_id; - uint16_t base; -} u8_displacement_t; - -/* - * The U8_TBL_ELEMENT_NOT_DEF macro indicates a byte that is not defined or - * used. The U8_TBL_ELEMENT_FILLER indicates the end of a UTF-8 character at - * the final tables. - */ -#define U8_TBL_ELEMENT_NOT_DEF (0xff) -#define N_ U8_TBL_ELEMENT_NOT_DEF - -#define U8_TBL_ELEMENT_FILLER (0xf7) -#define FIL_ U8_TBL_ELEMENT_FILLER - -/* - * The common b1_tbl for combining class, decompositions, tolower, and - * toupper case conversion mappings. - */ -static const uchar_t u8_common_b1_tbl[2][256] = { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 1, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 1, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, -}; - -static const uchar_t u8_combining_class_b2_tbl[2][2][256] = { - { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 1, 2, 3, 4, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, 5, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, 6, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - - }, - { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 1, 2, 3, 4, N_, N_, N_, N_, - N_, N_, 5, N_, N_, N_, N_, 6, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 7, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, 8, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - - }, - -}; - -static const uchar_t u8_combining_class_b3_tbl[2][9][256] = { - { - { /* Third byte table 0. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, 0, 1, N_, N_, - N_, N_, 2, N_, N_, N_, 3, 4, - N_, 5, N_, 6, 7, 8, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 1. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, N_, 19, - N_, 20, N_, 21, N_, 22, N_, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 2. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 32, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, 33, N_, N_, 34, - N_, N_, 35, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 3. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, 36, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 4. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 37, N_, 38, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 5. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, 39, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 40, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 6. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, 41, 42, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 7. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 8. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - }, - { - { /* Third byte table 0. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, 0, 1, N_, N_, - N_, N_, 2, N_, N_, N_, 3, 4, - 5, 6, N_, 7, 8, 9, N_, 10, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 1. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, N_, 21, - N_, 22, 23, 24, N_, 25, N_, 26, - 27, 28, 29, 30, 31, 32, 33, 34, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 2. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 35, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, 36, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, 37, N_, N_, 38, - N_, N_, 39, N_, 40, N_, N_, N_, - 41, N_, N_, N_, 42, 43, N_, N_, - N_, N_, N_, N_, N_, N_, N_, 44, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 3. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, 45, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 4. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 46, N_, 47, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 5. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 48, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 6. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, 49, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 50, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 7. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 51, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { /* Third byte table 8. */ - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, 52, 53, N_, - N_, 54, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - }, -}; - -/* - * Unlike other b4_tbl, the b4_tbl for combining class data has - * the combining class values not indices to the final tables. - */ -static const uchar_t u8_combining_class_b4_tbl[2][55][256] = { - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 232, 220, 220, - 220, 220, 232, 216, 220, 220, 220, 220, - 220, 202, 202, 220, 220, 220, 220, 202, - 202, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 1, 1, 1, 1, - 1, 220, 220, 220, 220, 230, 230, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 230, 230, 230, 240, 230, 220, - 220, 220, 230, 230, 230, 220, 220, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 234, 234, 233, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 230, 230, 230, 230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 220, 230, 230, 230, 230, 220, 230, - 230, 230, 222, 220, 230, 230, 230, 230, - 230, 230, 0, 220, 220, 220, 220, 220, - 230, 230, 220, 230, 230, 222, 228, 230, - 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 0, 20, 21, 22, 0, 23, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 24, 25, 0, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34, 230, 230, 220, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 35, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 230, 230, - 230, 230, 230, 230, 230, 0, 0, 230, - 230, 230, 230, 220, 230, 0, 0, 230, - 230, 0, 220, 230, 230, 220, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 36, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 220, 230, 230, 220, 230, 230, 220, - 220, 220, 230, 220, 220, 230, 220, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 220, 230, 220, 230, 220, 230, - 220, 230, 230, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 230, 220, 230, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 84, 91, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 103, 103, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 107, 107, 107, 107, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 118, 118, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 122, 122, 122, 122, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 220, 220, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 220, 0, 220, - 0, 216, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 129, 130, 0, 132, 0, 0, 0, - 0, 0, 130, 130, 130, 130, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 130, 0, 230, 230, 9, 0, 230, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 220, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 0, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 36. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 1, 1, 230, 230, 230, 230, - 1, 1, 1, 230, 230, 0, 0, 0, - 0, 230, 0, 0, 0, 1, 1, 230, - 220, 230, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 37. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 218, 228, 232, 222, 224, 224, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 38. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 39. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 26, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 40. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 230, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 41. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 216, 216, 1, - 1, 1, 0, 0, 0, 226, 216, 216, - 216, 216, 216, 0, 0, 0, 0, 0, - 0, 0, 0, 220, 220, 220, 220, 220, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 42. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 220, 220, 220, 0, 0, 230, 230, 230, - 230, 230, 220, 220, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 230, 230, 230, 230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 43. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 44. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 45. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 46. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 47. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 48. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 49. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 50. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 51. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 52. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 53. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 54. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - }, - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 232, 220, 220, - 220, 220, 232, 216, 220, 220, 220, 220, - 220, 202, 202, 220, 220, 220, 220, 202, - 202, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 1, 1, 1, 1, - 1, 220, 220, 220, 220, 230, 230, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 230, 230, 230, 240, 230, 220, - 220, 220, 230, 230, 230, 220, 220, 0, - 230, 230, 230, 220, 220, 220, 220, 230, - 232, 220, 220, 230, 233, 234, 234, 233, - 234, 234, 233, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 230, 230, 230, 230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 220, 230, 230, 230, 230, 220, 230, - 230, 230, 222, 220, 230, 230, 230, 230, - 230, 230, 220, 220, 220, 220, 220, 220, - 230, 230, 220, 230, 230, 222, 228, 230, - 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 19, 20, 21, 22, 0, 23, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 24, 25, 0, 230, 220, 0, 18, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 230, 230, 230, 230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34, 230, 230, 220, 220, 230, - 230, 230, 230, 230, 220, 230, 230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 35, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 230, 230, - 230, 230, 230, 230, 230, 0, 0, 230, - 230, 230, 230, 220, 230, 0, 0, 230, - 230, 0, 220, 230, 230, 220, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 36, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 220, 230, 230, 220, 230, 230, 220, - 220, 220, 230, 220, 220, 230, 220, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 220, 230, 220, 230, 220, 230, - 220, 230, 230, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 230, 230, 230, 230, 230, - 230, 230, 220, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 230, 220, 230, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 84, 91, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 103, 103, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 107, 107, 107, 107, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 118, 118, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 122, 122, 122, 122, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 220, 220, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 220, 0, 220, - 0, 216, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 129, 130, 0, 132, 0, 0, 0, - 0, 0, 130, 130, 130, 130, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 130, 0, 230, 230, 9, 0, 230, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 220, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 0, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 36. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 37. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 38. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 39. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 40. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 222, 230, 220, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 41. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 230, - 220, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 42. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 43. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 230, 220, 230, 230, 230, - 230, 230, 230, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 44. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 220, 230, 230, 230, 230, 230, - 230, 230, 220, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 230, 220, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 45. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 1, 1, 230, 230, 230, 230, - 1, 1, 1, 230, 230, 0, 0, 0, - 0, 230, 0, 0, 0, 1, 1, 230, - 220, 230, 1, 1, 220, 220, 220, 220, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 46. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 218, 228, 232, 222, 224, 224, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 47. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 48. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 49. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 26, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 50. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 230, 230, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 51. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 220, 0, 230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 230, 1, 220, 0, 0, 0, 0, 9, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 52. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 216, 216, 1, - 1, 1, 0, 0, 0, 226, 216, 216, - 216, 216, 216, 0, 0, 0, 0, 0, - 0, 0, 0, 220, 220, 220, 220, 220, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 53. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 220, 220, 220, 0, 0, 230, 230, 230, - 230, 230, 220, 220, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 230, 230, 230, 230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - { /* Fourth byte table 54. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 230, 230, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - }, -}; - -static const uchar_t u8_composition_b1_tbl[2][256] = { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, -}; - -static const uchar_t u8_composition_b2_tbl[2][1][256] = { - { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 1, 2, 3, 4, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - - }, - { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 1, 2, 3, 4, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - - }, - -}; - -static const u8_displacement_t u8_composition_b3_tbl[2][5][256] = { - { - { /* Third byte table 0. */ - { 0x8000, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0, 2470 }, - { 0x8001, 2491 }, { 1, 2871 }, { 2, 2959 }, - { 3, 3061 }, { 4, 3212 }, { 5, 3226 }, - { N_, 0 }, { 6, 3270 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0x8002, 3277 }, - { 7, 3774 }, { 8, 3949 }, { 9, 4198 }, - { N_, 0 }, { 10, 4265 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 11, 4293 }, { 12, 4312 }, { N_, 0 }, - { 13, 4326 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 1. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 14, 4347 }, - { N_, 0 }, { N_, 0 }, { 15, 4374 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 16, 4391 }, - { 17, 4416 }, { 18, 4425 }, { N_, 0 }, - { 19, 4451 }, { 20, 4460 }, { 21, 4469 }, - { N_, 0 }, { 22, 4503 }, { N_, 0 }, - { 23, 4529 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 2. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 24, 4563 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 25, 4572 }, { 26, 4588 }, - { 27, 4620 }, { 28, 4666 }, { 0x8003, 4682 }, - { 0x8004, 5254 }, { 29, 5616 }, { 30, 5646 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 3. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 31, 5684 }, - { 32, 5708 }, { 33, 5732 }, { 34, 5780 }, - { 35, 5900 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 4. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 36, 6012 }, { 37, 6241 }, { 38, 6358 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - }, - { - { /* Third byte table 0. */ - { 0x8000, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0, 2470 }, - { 0x8001, 2491 }, { 1, 2871 }, { 2, 2959 }, - { 3, 3061 }, { 4, 3212 }, { 5, 3226 }, - { N_, 0 }, { 6, 3270 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0x8002, 3277 }, - { 7, 3774 }, { 8, 3949 }, { 9, 4198 }, - { N_, 0 }, { 10, 4265 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 11, 4293 }, { 12, 4312 }, { N_, 0 }, - { 13, 4326 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 1. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 14, 4347 }, - { N_, 0 }, { N_, 0 }, { 15, 4374 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 16, 4391 }, - { 17, 4416 }, { 18, 4425 }, { N_, 0 }, - { 19, 4451 }, { 20, 4460 }, { 21, 4469 }, - { N_, 0 }, { 22, 4503 }, { N_, 0 }, - { 23, 4529 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 2. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 24, 4563 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 25, 4572 }, { 26, 4662 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 27, 4671 }, { 28, 4687 }, - { 29, 4719 }, { 30, 4765 }, { 0x8003, 4781 }, - { 0x8004, 5353 }, { 31, 5715 }, { 32, 5745 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 3. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 33, 5783 }, - { 34, 5807 }, { 35, 5831 }, { 36, 5879 }, - { 37, 5999 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 4. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 38, 6111 }, { 39, 6340 }, { 40, 6457 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - }, -}; - -static const uchar_t u8_composition_b4_tbl[2][41][257] = { - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 29, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 73, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 15, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 38, 46, 46, 46, 46, - 46, 54, 62, 62, 62, 62, 62, 62, - 62, 70, 78, 86, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 36, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 108, 144, 144, 144, 144, 144, 144, 144, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 14, 22, 30, 30, 30, 30, 30, 37, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 70, 70, - 70, 70, 112, 133, 154, 154, 154, 162, - 162, 162, 162, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 20, 20, 20, 27, 27, 46, 59, - 66, 91, 91, 98, 98, 98, 98, 105, - 105, 105, 105, 105, 130, 130, 130, 130, - 137, 137, 137, 137, 144, 144, 151, 151, - 151, 164, 164, 164, 171, 171, 190, 203, - 210, 235, 235, 242, 242, 242, 242, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 25, 25, 25, 25, - 32, 32, 32, 32, 39, 39, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 60, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 21, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 14, 14, 14, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, - 9, 18, 18, 18, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 25, - 25, 25, 25, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 16, 16, 16, 16, - 16, 16, 16, 24, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 38, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 8, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 16, - 16, 16, 16, 16, 16, 16, 16, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 8, 16, 16, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 8, 16, 16, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 8, 8, 8, - 8, 16, 16, 16, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 32, 32, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 8, 16, 16, - 16, 24, 24, 24, 24, 24, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 40, 40, 40, 48, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 64, 72, 72, 72, 80, - 88, 88, 88, 96, 104, 112, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 16, 16, 16, 24, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 40, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 56, 56, 56, 56, 56, - 56, 64, 72, 72, 80, 80, 80, 80, - 80, 80, 80, 88, 96, 104, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, - }, - { /* Fourth byte table 36. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 18, 18, 27, 27, - 36, 36, 45, 45, 54, 54, 63, 63, - 72, 72, 81, 81, 90, 90, 99, 99, - 108, 108, 117, 117, 117, 126, 126, 135, - 135, 144, 144, 144, 144, 144, 144, 144, - 161, 161, 161, 178, 178, 178, 195, 195, - 195, 212, 212, 212, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, - }, - { /* Fourth byte table 37. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 18, - 18, 18, 18, 18, 27, 27, 36, 36, - 45, 45, 54, 54, 63, 63, 72, 72, - 81, 81, 90, 90, 99, 99, 108, 108, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, - }, - { /* Fourth byte table 38. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 18, 18, 27, - 27, 36, 36, 36, 36, 36, 36, 36, - 53, 53, 53, 70, 70, 70, 87, 87, - 87, 104, 104, 104, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, - 130, 139, 148, 157, 157, 157, 157, 157, - 157, 157, 157, 157, 157, 157, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, - }, - { /* Fourth byte table 39. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 40. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - }, - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 29, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 73, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 15, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 38, 46, 46, 46, 46, - 46, 54, 62, 62, 62, 62, 62, 62, - 62, 70, 78, 86, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 36, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 108, 144, 144, 144, 144, 144, 144, 144, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, - 151, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 14, 22, 30, 30, 30, 30, 30, 37, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 70, 70, - 70, 70, 112, 133, 154, 154, 154, 162, - 162, 162, 162, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 20, 20, 20, 27, 27, 46, 59, - 66, 91, 91, 98, 98, 98, 98, 105, - 105, 105, 105, 105, 130, 130, 130, 130, - 137, 137, 137, 137, 144, 144, 151, 151, - 151, 164, 164, 164, 171, 171, 190, 203, - 210, 235, 235, 242, 242, 242, 242, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, - 249, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 25, 25, 25, 25, - 32, 32, 32, 32, 39, 39, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 60, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 21, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 14, 14, 14, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, - 9, 18, 18, 18, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 25, - 25, 25, 25, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, - 34, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, - 18, 18, 27, 27, 36, 36, 45, 45, - 45, 45, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 63, 63, 72, 72, 81, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 16, 16, 16, 16, - 16, 16, 16, 24, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 38, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 8, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 16, - 16, 16, 16, 16, 16, 16, 16, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 8, 16, 16, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 8, 16, 16, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 8, 8, 8, - 8, 16, 16, 16, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 32, 32, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 36. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 8, 16, 16, - 16, 24, 24, 24, 24, 24, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 40, 40, 40, 48, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 64, 72, 72, 72, 80, - 88, 88, 88, 96, 104, 112, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, - }, - { /* Fourth byte table 37. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 16, 16, 16, 24, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 40, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 56, 56, 56, 56, 56, - 56, 64, 72, 72, 80, 80, 80, 80, - 80, 80, 80, 88, 96, 104, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, - }, - { /* Fourth byte table 38. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 18, 18, 27, 27, - 36, 36, 45, 45, 54, 54, 63, 63, - 72, 72, 81, 81, 90, 90, 99, 99, - 108, 108, 117, 117, 117, 126, 126, 135, - 135, 144, 144, 144, 144, 144, 144, 144, - 161, 161, 161, 178, 178, 178, 195, 195, - 195, 212, 212, 212, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, - 229, - }, - { /* Fourth byte table 39. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 18, - 18, 18, 18, 18, 27, 27, 36, 36, - 45, 45, 54, 54, 63, 63, 72, 72, - 81, 81, 90, 90, 99, 99, 108, 108, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, - 117, - }, - { /* Fourth byte table 40. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 18, 18, 27, - 27, 36, 36, 36, 36, 36, 36, 36, - 53, 53, 53, 70, 70, 70, 87, 87, - 87, 104, 104, 104, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, - 130, 139, 148, 157, 157, 157, 157, 157, - 157, 157, 157, 157, 157, 157, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, - }, - }, -}; - -static const uint16_t u8_composition_b4_16bit_tbl[2][5][257] = { - { - { /* Fourth byte 16-bit table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 8, 16, 24, - 24, 24, 124, 146, 177, 219, 327, 335, - 379, 427, 521, 528, 562, 602, 624, 683, - 782, 797, 797, 849, 894, 941, 1061, 1076, - 1118, 1133, 1193, 1233, 1233, 1233, 1233, 1233, - 1233, 1233, 1333, 1355, 1386, 1428, 1536, 1544, - 1588, 1643, 1731, 1744, 1778, 1818, 1840, 1899, - 1998, 2013, 2013, 2065, 2110, 2164, 2284, 2299, - 2348, 2363, 2430, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, - }, - { /* Fourth byte 16-bit table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 29, 29, 36, 43, 56, - 64, 64, 64, 93, 93, 93, 93, 93, - 101, 101, 101, 101, 101, 130, 151, 158, - 158, 165, 165, 165, 165, 190, 190, 190, - 190, 190, 190, 219, 219, 226, 233, 246, - 254, 254, 254, 283, 283, 283, 283, 283, - 291, 291, 291, 291, 291, 320, 341, 348, - 348, 355, 355, 355, 355, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, - }, - { /* Fourth byte 16-bit table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 49, 49, 49, 49, 77, 77, - 112, 112, 160, 160, 160, 160, 160, 160, - 188, 188, 196, 196, 196, 196, 237, 237, - 237, 237, 272, 272, 272, 280, 280, 288, - 288, 288, 344, 344, 344, 344, 372, 372, - 414, 414, 469, 469, 469, 469, 469, 469, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, - }, - { /* Fourth byte 16-bit table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 29, 58, 66, 74, 82, 90, 98, - 106, 135, 164, 172, 180, 188, 196, 204, - 212, 227, 242, 242, 242, 242, 242, 242, - 242, 257, 272, 272, 272, 272, 272, 272, - 272, 301, 330, 338, 346, 354, 362, 370, - 378, 407, 436, 444, 452, 460, 468, 476, - 484, 506, 528, 528, 528, 528, 528, 528, - 528, 550, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, - }, - { /* Fourth byte 16-bit table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 30, 30, 30, 30, 30, 30, - 30, 45, 60, 60, 60, 60, 60, 60, - 60, 82, 104, 104, 104, 104, 104, 104, - 104, 104, 126, 126, 126, 126, 126, 126, - 126, 155, 184, 192, 200, 208, 216, 224, - 232, 261, 290, 298, 306, 314, 322, 330, - 338, 346, 346, 346, 346, 354, 354, 354, - 354, 354, 354, 354, 354, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, - }, - }, - { - { /* Fourth byte 16-bit table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 8, 16, 24, - 24, 24, 124, 146, 177, 219, 327, 335, - 379, 427, 521, 528, 562, 602, 624, 683, - 782, 797, 797, 849, 894, 941, 1061, 1076, - 1118, 1133, 1193, 1233, 1233, 1233, 1233, 1233, - 1233, 1233, 1333, 1355, 1386, 1428, 1536, 1544, - 1588, 1643, 1731, 1744, 1778, 1818, 1840, 1899, - 1998, 2013, 2013, 2065, 2110, 2164, 2284, 2299, - 2348, 2363, 2430, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, 2470, 2470, 2470, 2470, 2470, 2470, 2470, - 2470, - }, - { /* Fourth byte 16-bit table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 29, 29, 36, 43, 56, - 64, 64, 64, 93, 93, 93, 93, 93, - 101, 101, 101, 101, 101, 130, 151, 158, - 158, 165, 165, 165, 165, 190, 190, 190, - 190, 190, 190, 219, 219, 226, 233, 246, - 254, 254, 254, 283, 283, 283, 283, 283, - 291, 291, 291, 291, 291, 320, 341, 348, - 348, 355, 355, 355, 355, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, - }, - { /* Fourth byte 16-bit table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 49, 49, 49, 49, 77, 77, - 112, 112, 160, 160, 160, 160, 160, 160, - 188, 188, 196, 196, 196, 196, 237, 237, - 237, 237, 272, 272, 272, 280, 280, 288, - 288, 288, 344, 344, 344, 344, 372, 372, - 414, 414, 469, 469, 469, 469, 469, 469, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, - 497, - }, - { /* Fourth byte 16-bit table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 29, 58, 66, 74, 82, 90, 98, - 106, 135, 164, 172, 180, 188, 196, 204, - 212, 227, 242, 242, 242, 242, 242, 242, - 242, 257, 272, 272, 272, 272, 272, 272, - 272, 301, 330, 338, 346, 354, 362, 370, - 378, 407, 436, 444, 452, 460, 468, 476, - 484, 506, 528, 528, 528, 528, 528, 528, - 528, 550, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 572, 572, 572, 572, - 572, - }, - { /* Fourth byte 16-bit table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 30, 30, 30, 30, 30, 30, - 30, 45, 60, 60, 60, 60, 60, 60, - 60, 82, 104, 104, 104, 104, 104, 104, - 104, 104, 126, 126, 126, 126, 126, 126, - 126, 155, 184, 192, 200, 208, 216, 224, - 232, 261, 290, 298, 306, 314, 322, 330, - 338, 346, 346, 346, 346, 354, 354, 354, - 354, 354, 354, 354, 354, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, - }, - }, -}; - -static const uchar_t u8_composition_final_tbl[2][6623] = { - { - 0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAE, FIL_, - 0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xA0, FIL_, - 0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAF, FIL_, - 0x10, 0xCC, 0x86, FIL_, 0xC4, 0x82, FIL_, 0xCC, - 0x87, FIL_, 0xC8, 0xA6, FIL_, 0xCC, 0x8F, FIL_, - 0xC8, 0x80, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x82, - FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x81, FIL_, 0xCC, - 0x80, FIL_, 0xC3, 0x80, FIL_, 0xCC, 0x83, FIL_, - 0xC3, 0x83, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, - 0xA0, FIL_, 0xCC, 0xA5, FIL_, 0xE1, 0xB8, 0x80, - FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x82, FIL_, 0xCC, - 0x84, FIL_, 0xC4, 0x80, FIL_, 0xCC, 0x88, FIL_, - 0xC3, 0x84, FIL_, 0xCC, 0x8A, FIL_, 0xC3, 0x85, - FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x84, FIL_, 0xCC, - 0x89, FIL_, 0xE1, 0xBA, 0xA2, FIL_, 0xCC, 0x8C, - FIL_, 0xC7, 0x8D, FIL_, 0x03, 0xCC, 0x87, FIL_, - 0xE1, 0xB8, 0x82, FIL_, 0xCC, 0xB1, FIL_, 0xE1, - 0xB8, 0x86, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, - 0x84, FIL_, 0x05, 0xCC, 0xA7, FIL_, 0xC3, 0x87, - FIL_, 0xCC, 0x81, FIL_, 0xC4, 0x86, FIL_, 0xCC, - 0x8C, FIL_, 0xC4, 0x8C, FIL_, 0xCC, 0x87, FIL_, - 0xC4, 0x8A, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0x88, - FIL_, 0x06, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0x8E, - FIL_, 0xCC, 0xA7, FIL_, 0xE1, 0xB8, 0x90, FIL_, - 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0x92, FIL_, 0xCC, - 0x87, FIL_, 0xE1, 0xB8, 0x8A, FIL_, 0xCC, 0x8C, - FIL_, 0xC4, 0x8E, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xB8, 0x8C, FIL_, 0x11, 0xCC, 0x80, FIL_, 0xC3, - 0x88, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x89, FIL_, - 0xCC, 0x82, FIL_, 0xC3, 0x8A, FIL_, 0xCC, 0x88, - FIL_, 0xC3, 0x8B, FIL_, 0xCC, 0xA7, FIL_, 0xC8, - 0xA8, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x86, FIL_, - 0xCC, 0x8F, FIL_, 0xC8, 0x84, FIL_, 0xCC, 0x89, - FIL_, 0xE1, 0xBA, 0xBA, FIL_, 0xCC, 0xB0, FIL_, - 0xE1, 0xB8, 0x9A, FIL_, 0xCC, 0xAD, FIL_, 0xE1, - 0xB8, 0x98, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBA, - 0xBC, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0xB8, - FIL_, 0xCC, 0x84, FIL_, 0xC4, 0x92, FIL_, 0xCC, - 0x86, FIL_, 0xC4, 0x94, FIL_, 0xCC, 0x87, FIL_, - 0xC4, 0x96, FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x98, - FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x9A, FIL_, 0x01, - 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x9E, FIL_, 0x07, - 0xCC, 0x8C, FIL_, 0xC7, 0xA6, FIL_, 0xCC, 0x87, - FIL_, 0xC4, 0xA0, FIL_, 0xCC, 0x84, FIL_, 0xE1, - 0xB8, 0xA0, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0x9C, - FIL_, 0xCC, 0x81, FIL_, 0xC7, 0xB4, FIL_, 0xCC, - 0xA7, FIL_, 0xC4, 0xA2, FIL_, 0xCC, 0x86, FIL_, - 0xC4, 0x9E, FIL_, 0x07, 0xCC, 0xAE, FIL_, 0xE1, - 0xB8, 0xAA, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB8, - 0xA2, FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB8, 0xA6, - FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, 0xA4, FIL_, - 0xCC, 0xA7, FIL_, 0xE1, 0xB8, 0xA8, FIL_, 0xCC, - 0x8C, FIL_, 0xC8, 0x9E, FIL_, 0xCC, 0x82, FIL_, - 0xC4, 0xA4, FIL_, 0x0F, 0xCC, 0x84, FIL_, 0xC4, - 0xAA, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x8C, FIL_, - 0xCC, 0xA8, FIL_, 0xC4, 0xAE, FIL_, 0xCC, 0x83, - FIL_, 0xC4, 0xA8, FIL_, 0xCC, 0x88, FIL_, 0xC3, - 0x8F, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x8D, FIL_, - 0xCC, 0x8F, FIL_, 0xC8, 0x88, FIL_, 0xCC, 0x86, - FIL_, 0xC4, 0xAC, FIL_, 0xCC, 0x91, FIL_, 0xC8, - 0x8A, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x8F, FIL_, - 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x88, FIL_, 0xCC, - 0x87, FIL_, 0xC4, 0xB0, FIL_, 0xCC, 0xA3, FIL_, - 0xE1, 0xBB, 0x8A, FIL_, 0xCC, 0xB0, FIL_, 0xE1, - 0xB8, 0xAC, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x8E, - FIL_, 0x01, 0xCC, 0x82, FIL_, 0xC4, 0xB4, FIL_, - 0x05, 0xCC, 0x8C, FIL_, 0xC7, 0xA8, FIL_, 0xCC, - 0xB1, FIL_, 0xE1, 0xB8, 0xB4, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xB8, 0xB0, FIL_, 0xCC, 0xA7, FIL_, - 0xC4, 0xB6, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, - 0xB2, FIL_, 0x06, 0xCC, 0xA7, FIL_, 0xC4, 0xBB, - FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0xBD, FIL_, 0xCC, - 0xB1, FIL_, 0xE1, 0xB8, 0xBA, FIL_, 0xCC, 0xA3, - FIL_, 0xE1, 0xB8, 0xB6, FIL_, 0xCC, 0xAD, FIL_, - 0xE1, 0xB8, 0xBC, FIL_, 0xCC, 0x81, FIL_, 0xC4, - 0xB9, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xB8, - 0xBE, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x82, - FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x80, FIL_, - 0x09, 0xCC, 0x80, FIL_, 0xC7, 0xB8, FIL_, 0xCC, - 0xAD, FIL_, 0xE1, 0xB9, 0x8A, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0x84, FIL_, 0xCC, 0xB1, FIL_, - 0xE1, 0xB9, 0x88, FIL_, 0xCC, 0x83, FIL_, 0xC3, - 0x91, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x86, - FIL_, 0xCC, 0x81, FIL_, 0xC5, 0x83, FIL_, 0xCC, - 0xA7, FIL_, 0xC5, 0x85, FIL_, 0xCC, 0x8C, FIL_, - 0xC5, 0x87, FIL_, 0x10, 0xCC, 0xA8, FIL_, 0xC7, - 0xAA, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x8E, FIL_, - 0xCC, 0x80, FIL_, 0xC3, 0x92, FIL_, 0xCC, 0x9B, - FIL_, 0xC6, 0xA0, FIL_, 0xCC, 0x8F, FIL_, 0xC8, - 0x8C, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x93, FIL_, - 0xCC, 0x87, FIL_, 0xC8, 0xAE, FIL_, 0xCC, 0x8C, - FIL_, 0xC7, 0x91, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xBB, 0x8C, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x94, - FIL_, 0xCC, 0x84, FIL_, 0xC5, 0x8C, FIL_, 0xCC, - 0x83, FIL_, 0xC3, 0x95, FIL_, 0xCC, 0x86, FIL_, - 0xC5, 0x8E, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x96, - FIL_, 0xCC, 0x8B, FIL_, 0xC5, 0x90, FIL_, 0xCC, - 0x89, FIL_, 0xE1, 0xBB, 0x8E, FIL_, 0x02, 0xCC, - 0x87, FIL_, 0xE1, 0xB9, 0x96, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0x94, FIL_, 0x08, 0xCC, 0x91, - FIL_, 0xC8, 0x92, FIL_, 0xCC, 0xA7, FIL_, 0xC5, - 0x96, FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0x98, FIL_, - 0xCC, 0xB1, FIL_, 0xE1, 0xB9, 0x9E, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xB9, 0x9A, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0x98, FIL_, 0xCC, 0x81, FIL_, - 0xC5, 0x94, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x90, - FIL_, 0x07, 0xCC, 0x81, FIL_, 0xC5, 0x9A, FIL_, - 0xCC, 0x82, FIL_, 0xC5, 0x9C, FIL_, 0xCC, 0xA7, - FIL_, 0xC5, 0x9E, FIL_, 0xCC, 0x8C, FIL_, 0xC5, - 0xA0, FIL_, 0xCC, 0xA6, FIL_, 0xC8, 0x98, FIL_, - 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xA0, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xB9, 0xA2, FIL_, 0x07, 0xCC, - 0x8C, FIL_, 0xC5, 0xA4, FIL_, 0xCC, 0xB1, FIL_, - 0xE1, 0xB9, 0xAE, FIL_, 0xCC, 0xA6, FIL_, 0xC8, - 0x9A, FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0xA2, FIL_, - 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xAA, FIL_, 0xCC, - 0xAD, FIL_, 0xE1, 0xB9, 0xB0, FIL_, 0xCC, 0xA3, - FIL_, 0xE1, 0xB9, 0xAC, FIL_, 0x13, 0xCC, 0xA8, - FIL_, 0xC5, 0xB2, FIL_, 0xCC, 0x83, FIL_, 0xC5, - 0xA8, FIL_, 0xCC, 0x84, FIL_, 0xC5, 0xAA, FIL_, - 0xCC, 0x81, FIL_, 0xC3, 0x9A, FIL_, 0xCC, 0x86, - FIL_, 0xC5, 0xAC, FIL_, 0xCC, 0x8A, FIL_, 0xC5, - 0xAE, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x99, FIL_, - 0xCC, 0x91, FIL_, 0xC8, 0x96, FIL_, 0xCC, 0x8B, - FIL_, 0xC5, 0xB0, FIL_, 0xCC, 0xA4, FIL_, 0xE1, - 0xB9, 0xB2, FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB9, - 0xB4, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x94, FIL_, - 0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0xB6, FIL_, 0xCC, - 0x9B, FIL_, 0xC6, 0xAF, FIL_, 0xCC, 0x82, FIL_, - 0xC3, 0x9B, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x9C, - FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x93, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xBB, 0xA4, FIL_, 0xCC, 0x89, - FIL_, 0xE1, 0xBB, 0xA6, FIL_, 0x02, 0xCC, 0x83, - FIL_, 0xE1, 0xB9, 0xBC, FIL_, 0xCC, 0xA3, FIL_, - 0xE1, 0xB9, 0xBE, FIL_, 0x06, 0xCC, 0x82, FIL_, - 0xC5, 0xB4, FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xBA, - 0x84, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xBA, 0x86, - FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x88, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0x82, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBA, 0x80, FIL_, 0x02, 0xCC, - 0x87, FIL_, 0xE1, 0xBA, 0x8A, FIL_, 0xCC, 0x88, - FIL_, 0xE1, 0xBA, 0x8C, FIL_, 0x09, 0xCC, 0x89, - FIL_, 0xE1, 0xBB, 0xB6, FIL_, 0xCC, 0x87, FIL_, - 0xE1, 0xBA, 0x8E, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xBB, 0xB4, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x9D, - FIL_, 0xCC, 0x84, FIL_, 0xC8, 0xB2, FIL_, 0xCC, - 0x82, FIL_, 0xC5, 0xB6, FIL_, 0xCC, 0x88, FIL_, - 0xC5, 0xB8, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB, - 0xB2, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xB8, - FIL_, 0x06, 0xCC, 0x87, FIL_, 0xC5, 0xBB, FIL_, - 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x92, FIL_, 0xCC, - 0x8C, FIL_, 0xC5, 0xBD, FIL_, 0xCC, 0xB1, FIL_, - 0xE1, 0xBA, 0x94, FIL_, 0xCC, 0x82, FIL_, 0xE1, - 0xBA, 0x90, FIL_, 0xCC, 0x81, FIL_, 0xC5, 0xB9, - FIL_, 0x10, 0xCC, 0x8C, FIL_, 0xC7, 0x8E, FIL_, - 0xCC, 0x8F, FIL_, 0xC8, 0x81, FIL_, 0xCC, 0xA8, - FIL_, 0xC4, 0x85, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xBA, 0xA1, FIL_, 0xCC, 0x86, FIL_, 0xC4, 0x83, - FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xA3, FIL_, - 0xCC, 0x84, FIL_, 0xC4, 0x81, FIL_, 0xCC, 0x91, - FIL_, 0xC8, 0x83, FIL_, 0xCC, 0x8A, FIL_, 0xC3, - 0xA5, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0xA4, FIL_, - 0xCC, 0x83, FIL_, 0xC3, 0xA3, FIL_, 0xCC, 0x82, - FIL_, 0xC3, 0xA2, FIL_, 0xCC, 0x81, FIL_, 0xC3, - 0xA1, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0xA0, FIL_, - 0xCC, 0x87, FIL_, 0xC8, 0xA7, FIL_, 0xCC, 0xA5, - FIL_, 0xE1, 0xB8, 0x81, FIL_, 0x03, 0xCC, 0xB1, - FIL_, 0xE1, 0xB8, 0x87, FIL_, 0xCC, 0xA3, FIL_, - 0xE1, 0xB8, 0x85, FIL_, 0xCC, 0x87, FIL_, 0xE1, - 0xB8, 0x83, FIL_, 0x05, 0xCC, 0x87, FIL_, 0xC4, - 0x8B, FIL_, 0xCC, 0xA7, FIL_, 0xC3, 0xA7, FIL_, - 0xCC, 0x82, FIL_, 0xC4, 0x89, FIL_, 0xCC, 0x8C, - FIL_, 0xC4, 0x8D, FIL_, 0xCC, 0x81, FIL_, 0xC4, - 0x87, FIL_, 0x06, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, - 0x93, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x8B, - FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, 0x8D, FIL_, - 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0x8F, FIL_, 0xCC, - 0xA7, FIL_, 0xE1, 0xB8, 0x91, FIL_, 0xCC, 0x8C, - FIL_, 0xC4, 0x8F, FIL_, 0x11, 0xCC, 0xA8, FIL_, - 0xC4, 0x99, FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x9B, - FIL_, 0xCC, 0x87, FIL_, 0xC4, 0x97, FIL_, 0xCC, - 0x88, FIL_, 0xC3, 0xAB, FIL_, 0xCC, 0xA3, FIL_, - 0xE1, 0xBA, 0xB9, FIL_, 0xCC, 0xB0, FIL_, 0xE1, - 0xB8, 0x9B, FIL_, 0xCC, 0x84, FIL_, 0xC4, 0x93, - FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0x99, FIL_, - 0xCC, 0x83, FIL_, 0xE1, 0xBA, 0xBD, FIL_, 0xCC, - 0x86, FIL_, 0xC4, 0x95, FIL_, 0xCC, 0xA7, FIL_, - 0xC8, 0xA9, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, - 0xBB, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x85, FIL_, - 0xCC, 0x81, FIL_, 0xC3, 0xA9, FIL_, 0xCC, 0x91, - FIL_, 0xC8, 0x87, FIL_, 0xCC, 0x80, FIL_, 0xC3, - 0xA8, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xAA, FIL_, - 0x01, 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x9F, FIL_, - 0x07, 0xCC, 0x86, FIL_, 0xC4, 0x9F, FIL_, 0xCC, - 0xA7, FIL_, 0xC4, 0xA3, FIL_, 0xCC, 0x81, FIL_, - 0xC7, 0xB5, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0x9D, - FIL_, 0xCC, 0x87, FIL_, 0xC4, 0xA1, FIL_, 0xCC, - 0x8C, FIL_, 0xC7, 0xA7, FIL_, 0xCC, 0x84, FIL_, - 0xE1, 0xB8, 0xA1, FIL_, 0x08, 0xCC, 0x8C, FIL_, - 0xC8, 0x9F, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0xA5, - FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB8, 0xA7, FIL_, - 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0xA3, FIL_, 0xCC, - 0xB1, FIL_, 0xE1, 0xBA, 0x96, FIL_, 0xCC, 0xA3, - FIL_, 0xE1, 0xB8, 0xA5, FIL_, 0xCC, 0xA7, FIL_, - 0xE1, 0xB8, 0xA9, FIL_, 0xCC, 0xAE, FIL_, 0xE1, - 0xB8, 0xAB, FIL_, 0x0E, 0xCC, 0x81, FIL_, 0xC3, - 0xAD, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0xAC, FIL_, - 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0x8B, FIL_, 0xCC, - 0x8C, FIL_, 0xC7, 0x90, FIL_, 0xCC, 0x89, FIL_, - 0xE1, 0xBB, 0x89, FIL_, 0xCC, 0x91, FIL_, 0xC8, - 0x8B, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x89, FIL_, - 0xCC, 0x82, FIL_, 0xC3, 0xAE, FIL_, 0xCC, 0xB0, - FIL_, 0xE1, 0xB8, 0xAD, FIL_, 0xCC, 0xA8, FIL_, - 0xC4, 0xAF, FIL_, 0xCC, 0x86, FIL_, 0xC4, 0xAD, - FIL_, 0xCC, 0x84, FIL_, 0xC4, 0xAB, FIL_, 0xCC, - 0x83, FIL_, 0xC4, 0xA9, FIL_, 0xCC, 0x88, FIL_, - 0xC3, 0xAF, FIL_, 0x02, 0xCC, 0x82, FIL_, 0xC4, - 0xB5, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0xB0, FIL_, - 0x05, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, 0xB3, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xB1, FIL_, 0xCC, - 0xA7, FIL_, 0xC4, 0xB7, FIL_, 0xCC, 0x8C, FIL_, - 0xC7, 0xA9, FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, - 0xB5, FIL_, 0x06, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, - 0xB7, FIL_, 0xCC, 0x81, FIL_, 0xC4, 0xBA, FIL_, - 0xCC, 0xA7, FIL_, 0xC4, 0xBC, FIL_, 0xCC, 0x8C, - FIL_, 0xC4, 0xBE, FIL_, 0xCC, 0xB1, FIL_, 0xE1, - 0xB8, 0xBB, FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, - 0xBD, FIL_, 0x03, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, - 0x83, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xBF, - FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x81, FIL_, - 0x09, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x87, FIL_, - 0xCC, 0x83, FIL_, 0xC3, 0xB1, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0x85, FIL_, 0xCC, 0xB1, FIL_, - 0xE1, 0xB9, 0x89, FIL_, 0xCC, 0x81, FIL_, 0xC5, - 0x84, FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0x86, FIL_, - 0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0x8B, FIL_, 0xCC, - 0x8C, FIL_, 0xC5, 0x88, FIL_, 0xCC, 0x80, FIL_, - 0xC7, 0xB9, FIL_, 0x10, 0xCC, 0x89, FIL_, 0xE1, - 0xBB, 0x8F, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0xB3, - FIL_, 0xCC, 0x80, FIL_, 0xC3, 0xB2, FIL_, 0xCC, - 0x87, FIL_, 0xC8, 0xAF, FIL_, 0xCC, 0x8F, FIL_, - 0xC8, 0x8D, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, - 0x8D, FIL_, 0xCC, 0x84, FIL_, 0xC5, 0x8D, FIL_, - 0xCC, 0x8C, FIL_, 0xC7, 0x92, FIL_, 0xCC, 0x86, - FIL_, 0xC5, 0x8F, FIL_, 0xCC, 0x8B, FIL_, 0xC5, - 0x91, FIL_, 0xCC, 0x9B, FIL_, 0xC6, 0xA1, FIL_, - 0xCC, 0x91, FIL_, 0xC8, 0x8F, FIL_, 0xCC, 0xA8, - FIL_, 0xC7, 0xAB, FIL_, 0xCC, 0x88, FIL_, 0xC3, - 0xB6, FIL_, 0xCC, 0x83, FIL_, 0xC3, 0xB5, FIL_, - 0xCC, 0x82, FIL_, 0xC3, 0xB4, FIL_, 0x02, 0xCC, - 0x87, FIL_, 0xE1, 0xB9, 0x97, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0x95, FIL_, 0x08, 0xCC, 0xB1, - FIL_, 0xE1, 0xB9, 0x9F, FIL_, 0xCC, 0x87, FIL_, - 0xE1, 0xB9, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xC5, - 0x95, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x91, FIL_, - 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x9B, FIL_, 0xCC, - 0x8C, FIL_, 0xC5, 0x99, FIL_, 0xCC, 0x91, FIL_, - 0xC8, 0x93, FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0x97, - FIL_, 0x07, 0xCC, 0xA6, FIL_, 0xC8, 0x99, FIL_, - 0xCC, 0x8C, FIL_, 0xC5, 0xA1, FIL_, 0xCC, 0x81, - FIL_, 0xC5, 0x9B, FIL_, 0xCC, 0x87, FIL_, 0xE1, - 0xB9, 0xA1, FIL_, 0xCC, 0x82, FIL_, 0xC5, 0x9D, - FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0x9F, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xB9, 0xA3, FIL_, 0x08, 0xCC, - 0x88, FIL_, 0xE1, 0xBA, 0x97, FIL_, 0xCC, 0xAD, - FIL_, 0xE1, 0xB9, 0xB1, FIL_, 0xCC, 0xB1, FIL_, - 0xE1, 0xB9, 0xAF, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xB9, 0xAD, FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0xA5, - FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0xA3, FIL_, 0xCC, - 0x87, FIL_, 0xE1, 0xB9, 0xAB, FIL_, 0xCC, 0xA6, - FIL_, 0xC8, 0x9B, FIL_, 0x13, 0xCC, 0x81, FIL_, - 0xC3, 0xBA, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x97, - FIL_, 0xCC, 0x83, FIL_, 0xC5, 0xA9, FIL_, 0xCC, - 0x8F, FIL_, 0xC8, 0x95, FIL_, 0xCC, 0xA8, FIL_, - 0xC5, 0xB3, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xBB, - FIL_, 0xCC, 0x88, FIL_, 0xC3, 0xBC, FIL_, 0xCC, - 0x80, FIL_, 0xC3, 0xB9, FIL_, 0xCC, 0xA3, FIL_, - 0xE1, 0xBB, 0xA5, FIL_, 0xCC, 0xA4, FIL_, 0xE1, - 0xB9, 0xB3, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, - 0xA7, FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB9, 0xB5, - FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0xB7, FIL_, - 0xCC, 0x9B, FIL_, 0xC6, 0xB0, FIL_, 0xCC, 0x84, - FIL_, 0xC5, 0xAB, FIL_, 0xCC, 0x8B, FIL_, 0xC5, - 0xB1, FIL_, 0xCC, 0x86, FIL_, 0xC5, 0xAD, FIL_, - 0xCC, 0x8C, FIL_, 0xC7, 0x94, FIL_, 0xCC, 0x8A, - FIL_, 0xC5, 0xAF, FIL_, 0x02, 0xCC, 0x83, FIL_, - 0xE1, 0xB9, 0xBD, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xB9, 0xBF, FIL_, 0x07, 0xCC, 0x82, FIL_, 0xC5, - 0xB5, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0x81, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0x83, FIL_, - 0xCC, 0x88, FIL_, 0xE1, 0xBA, 0x85, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xBA, 0x89, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xBA, 0x87, FIL_, 0xCC, 0x8A, FIL_, - 0xE1, 0xBA, 0x98, FIL_, 0x02, 0xCC, 0x87, FIL_, - 0xE1, 0xBA, 0x8B, FIL_, 0xCC, 0x88, FIL_, 0xE1, - 0xBA, 0x8D, FIL_, 0x0A, 0xCC, 0x87, FIL_, 0xE1, - 0xBA, 0x8F, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, - 0xB9, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0xB3, - FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0xB7, FIL_, - 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xB5, FIL_, 0xCC, - 0x82, FIL_, 0xC5, 0xB7, FIL_, 0xCC, 0x84, FIL_, - 0xC8, 0xB3, FIL_, 0xCC, 0x8A, FIL_, 0xE1, 0xBA, - 0x99, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0xBF, FIL_, - 0xCC, 0x81, FIL_, 0xC3, 0xBD, FIL_, 0x06, 0xCC, - 0x8C, FIL_, 0xC5, 0xBE, FIL_, 0xCC, 0x87, FIL_, - 0xC5, 0xBC, FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xBA, - 0x95, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x93, - FIL_, 0xCC, 0x81, FIL_, 0xC5, 0xBA, FIL_, 0xCC, - 0x82, FIL_, 0xE1, 0xBA, 0x91, FIL_, 0x03, 0xCC, - 0x80, FIL_, 0xE1, 0xBF, 0xAD, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBF, 0x81, FIL_, 0xCC, 0x81, FIL_, - 0xCE, 0x85, FIL_, 0x04, 0xCC, 0x89, FIL_, 0xE1, - 0xBA, 0xA8, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBA, - 0xAA, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xA4, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0xA6, FIL_, - 0x01, 0xCC, 0x84, FIL_, 0xC7, 0x9E, FIL_, 0x01, - 0xCC, 0x81, FIL_, 0xC7, 0xBA, FIL_, 0x02, 0xCC, - 0x84, FIL_, 0xC7, 0xA2, FIL_, 0xCC, 0x81, FIL_, - 0xC7, 0xBC, FIL_, 0x01, 0xCC, 0x81, FIL_, 0xE1, - 0xB8, 0x88, FIL_, 0x04, 0xCC, 0x81, FIL_, 0xE1, - 0xBA, 0xBE, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB, - 0x80, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0x84, - FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x82, FIL_, - 0x01, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xAE, FIL_, - 0x04, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0x96, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xBB, 0x90, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBB, 0x92, FIL_, 0xCC, 0x89, - FIL_, 0xE1, 0xBB, 0x94, FIL_, 0x03, 0xCC, 0x84, - FIL_, 0xC8, 0xAC, FIL_, 0xCC, 0x81, FIL_, 0xE1, - 0xB9, 0x8C, FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB9, - 0x8E, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC8, 0xAA, - FIL_, 0x01, 0xCC, 0x81, FIL_, 0xC7, 0xBE, FIL_, - 0x04, 0xCC, 0x80, FIL_, 0xC7, 0x9B, FIL_, 0xCC, - 0x84, FIL_, 0xC7, 0x95, FIL_, 0xCC, 0x8C, FIL_, - 0xC7, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xC7, 0x97, - FIL_, 0x04, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xA9, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0xA7, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xA5, FIL_, 0xCC, - 0x83, FIL_, 0xE1, 0xBA, 0xAB, FIL_, 0x01, 0xCC, - 0x84, FIL_, 0xC7, 0x9F, FIL_, 0x01, 0xCC, 0x81, - FIL_, 0xC7, 0xBB, FIL_, 0x02, 0xCC, 0x84, FIL_, - 0xC7, 0xA3, FIL_, 0xCC, 0x81, FIL_, 0xC7, 0xBD, - FIL_, 0x01, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x89, - FIL_, 0x04, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x83, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xBF, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0x81, FIL_, 0xCC, - 0x83, FIL_, 0xE1, 0xBB, 0x85, FIL_, 0x01, 0xCC, - 0x81, FIL_, 0xE1, 0xB8, 0xAF, FIL_, 0x04, 0xCC, - 0x83, FIL_, 0xE1, 0xBB, 0x97, FIL_, 0xCC, 0x89, - FIL_, 0xE1, 0xBB, 0x95, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBB, 0x93, FIL_, 0xCC, 0x81, FIL_, 0xE1, - 0xBB, 0x91, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, - 0xB9, 0x8D, FIL_, 0xCC, 0x84, FIL_, 0xC8, 0xAD, - FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB9, 0x8F, FIL_, - 0x01, 0xCC, 0x84, FIL_, 0xC8, 0xAB, FIL_, 0x01, - 0xCC, 0x81, FIL_, 0xC7, 0xBF, FIL_, 0x04, 0xCC, - 0x81, FIL_, 0xC7, 0x98, FIL_, 0xCC, 0x84, FIL_, - 0xC7, 0x96, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x9A, - FIL_, 0xCC, 0x80, FIL_, 0xC7, 0x9C, FIL_, 0x04, - 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0xB0, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xBA, 0xAE, FIL_, 0xCC, 0x83, - FIL_, 0xE1, 0xBA, 0xB4, FIL_, 0xCC, 0x89, FIL_, - 0xE1, 0xBA, 0xB2, FIL_, 0x04, 0xCC, 0x80, FIL_, - 0xE1, 0xBA, 0xB1, FIL_, 0xCC, 0x83, FIL_, 0xE1, - 0xBA, 0xB5, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, - 0xAF, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xB3, - FIL_, 0x02, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x96, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xB8, 0x94, FIL_, - 0x02, 0xCC, 0x80, FIL_, 0xE1, 0xB8, 0x95, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x97, FIL_, 0x02, - 0xCC, 0x80, FIL_, 0xE1, 0xB9, 0x90, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xB9, 0x92, FIL_, 0x02, 0xCC, - 0x80, FIL_, 0xE1, 0xB9, 0x91, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0x93, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA4, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA5, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA6, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA7, FIL_, 0x01, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0xB8, FIL_, 0x01, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0xB9, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xE1, 0xB9, 0xBA, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xE1, 0xB9, 0xBB, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xBA, 0x9B, FIL_, 0x05, 0xCC, 0x80, - FIL_, 0xE1, 0xBB, 0x9C, FIL_, 0xCC, 0x81, FIL_, - 0xE1, 0xBB, 0x9A, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xBB, 0xA2, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, - 0xA0, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x9E, - FIL_, 0x05, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xA1, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBB, 0x9B, FIL_, - 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xA3, FIL_, 0xCC, - 0x89, FIL_, 0xE1, 0xBB, 0x9F, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBB, 0x9D, FIL_, 0x05, 0xCC, 0x83, - FIL_, 0xE1, 0xBB, 0xAE, FIL_, 0xCC, 0xA3, FIL_, - 0xE1, 0xBB, 0xB0, FIL_, 0xCC, 0x89, FIL_, 0xE1, - 0xBB, 0xAC, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBB, - 0xA8, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0xAA, - FIL_, 0x05, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xB1, - FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xAF, FIL_, - 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0xAD, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xBB, 0xA9, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBB, 0xAB, FIL_, 0x01, 0xCC, 0x8C, - FIL_, 0xC7, 0xAE, FIL_, 0x01, 0xCC, 0x84, FIL_, - 0xC7, 0xAC, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, - 0xAD, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, 0xA0, - FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, 0xA1, FIL_, - 0x01, 0xCC, 0x86, FIL_, 0xE1, 0xB8, 0x9C, FIL_, - 0x01, 0xCC, 0x86, FIL_, 0xE1, 0xB8, 0x9D, FIL_, - 0x01, 0xCC, 0x84, FIL_, 0xC8, 0xB0, FIL_, 0x01, - 0xCC, 0x84, FIL_, 0xC8, 0xB1, FIL_, 0x01, 0xCC, - 0x8C, FIL_, 0xC7, 0xAF, FIL_, 0x07, 0xCC, 0x93, - FIL_, 0xE1, 0xBC, 0x88, FIL_, 0xCC, 0x94, FIL_, - 0xE1, 0xBC, 0x89, FIL_, 0xCC, 0x81, FIL_, 0xCE, - 0x86, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xBC, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBE, 0xBA, FIL_, - 0xCC, 0x84, FIL_, 0xE1, 0xBE, 0xB9, FIL_, 0xCC, - 0x86, FIL_, 0xE1, 0xBE, 0xB8, FIL_, 0x04, 0xCC, - 0x81, FIL_, 0xCE, 0x88, FIL_, 0xCC, 0x94, FIL_, - 0xE1, 0xBC, 0x99, FIL_, 0xCC, 0x93, FIL_, 0xE1, - 0xBC, 0x98, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, - 0x88, FIL_, 0x05, 0xCC, 0x94, FIL_, 0xE1, 0xBC, - 0xA9, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0x8A, - FIL_, 0xCC, 0x81, FIL_, 0xCE, 0x89, FIL_, 0xCD, - 0x85, FIL_, 0xE1, 0xBF, 0x8C, FIL_, 0xCC, 0x93, - FIL_, 0xE1, 0xBC, 0xA8, FIL_, 0x07, 0xCC, 0x81, - FIL_, 0xCE, 0x8A, FIL_, 0xCC, 0x88, FIL_, 0xCE, - 0xAA, FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBF, 0x98, - FIL_, 0xCC, 0x84, FIL_, 0xE1, 0xBF, 0x99, FIL_, - 0xCC, 0x93, FIL_, 0xE1, 0xBC, 0xB8, FIL_, 0xCC, - 0x94, FIL_, 0xE1, 0xBC, 0xB9, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBF, 0x9A, FIL_, 0x04, 0xCC, 0x94, - FIL_, 0xE1, 0xBD, 0x89, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBF, 0xB8, FIL_, 0xCC, 0x81, FIL_, 0xCE, - 0x8C, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBD, 0x88, - FIL_, 0x01, 0xCC, 0x94, FIL_, 0xE1, 0xBF, 0xAC, - FIL_, 0x06, 0xCC, 0x81, FIL_, 0xCE, 0x8E, FIL_, - 0xCC, 0x86, FIL_, 0xE1, 0xBF, 0xA8, FIL_, 0xCC, - 0x94, FIL_, 0xE1, 0xBD, 0x99, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBF, 0xAA, FIL_, 0xCC, 0x84, FIL_, - 0xE1, 0xBF, 0xA9, FIL_, 0xCC, 0x88, FIL_, 0xCE, - 0xAB, FIL_, 0x05, 0xCC, 0x80, FIL_, 0xE1, 0xBF, - 0xBA, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0x8F, FIL_, - 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xBC, FIL_, 0xCC, - 0x94, FIL_, 0xE1, 0xBD, 0xA9, FIL_, 0xCC, 0x93, - FIL_, 0xE1, 0xBD, 0xA8, FIL_, 0x01, 0xCD, 0x85, - FIL_, 0xE1, 0xBE, 0xB4, FIL_, 0x01, 0xCD, 0x85, - FIL_, 0xE1, 0xBF, 0x84, FIL_, 0x08, 0xCC, 0x81, - FIL_, 0xCE, 0xAC, FIL_, 0xCC, 0x80, FIL_, 0xE1, - 0xBD, 0xB0, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBC, - 0x80, FIL_, 0xCC, 0x94, FIL_, 0xE1, 0xBC, 0x81, - FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBE, 0xB6, FIL_, - 0xCC, 0x86, FIL_, 0xE1, 0xBE, 0xB0, FIL_, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xB3, FIL_, 0xCC, 0x84, - FIL_, 0xE1, 0xBE, 0xB1, FIL_, 0x04, 0xCC, 0x81, - FIL_, 0xCE, 0xAD, FIL_, 0xCC, 0x94, FIL_, 0xE1, - 0xBC, 0x91, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, - 0xB2, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBC, 0x90, - FIL_, 0x06, 0xCC, 0x81, FIL_, 0xCE, 0xAE, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xB4, FIL_, 0xCD, - 0x85, FIL_, 0xE1, 0xBF, 0x83, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBF, 0x86, FIL_, 0xCC, 0x94, FIL_, - 0xE1, 0xBC, 0xA1, FIL_, 0xCC, 0x93, FIL_, 0xE1, - 0xBC, 0xA0, FIL_, 0x08, 0xCD, 0x82, FIL_, 0xE1, - 0xBF, 0x96, FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBF, - 0x90, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBC, 0xB0, - FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAF, FIL_, 0xCC, - 0x94, FIL_, 0xE1, 0xBC, 0xB1, FIL_, 0xCC, 0x84, - FIL_, 0xE1, 0xBF, 0x91, FIL_, 0xCC, 0x88, FIL_, - 0xCF, 0x8A, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, - 0xB6, FIL_, 0x04, 0xCC, 0x81, FIL_, 0xCF, 0x8C, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xB8, FIL_, - 0xCC, 0x93, FIL_, 0xE1, 0xBD, 0x80, FIL_, 0xCC, - 0x94, FIL_, 0xE1, 0xBD, 0x81, FIL_, 0x02, 0xCC, - 0x93, FIL_, 0xE1, 0xBF, 0xA4, FIL_, 0xCC, 0x94, - FIL_, 0xE1, 0xBF, 0xA5, FIL_, 0x08, 0xCC, 0x93, - FIL_, 0xE1, 0xBD, 0x90, FIL_, 0xCC, 0x94, FIL_, - 0xE1, 0xBD, 0x91, FIL_, 0xCC, 0x86, FIL_, 0xE1, - 0xBF, 0xA0, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, - 0xA6, FIL_, 0xCC, 0x84, FIL_, 0xE1, 0xBF, 0xA1, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xBA, FIL_, - 0xCC, 0x81, FIL_, 0xCF, 0x8D, FIL_, 0xCC, 0x88, - FIL_, 0xCF, 0x8B, FIL_, 0x06, 0xCC, 0x94, FIL_, - 0xE1, 0xBD, 0xA1, FIL_, 0xCD, 0x85, FIL_, 0xE1, - 0xBF, 0xB3, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, - 0xBC, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0xB6, - FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBD, 0xA0, FIL_, - 0xCC, 0x81, FIL_, 0xCF, 0x8E, FIL_, 0x03, 0xCD, - 0x82, FIL_, 0xE1, 0xBF, 0x97, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBF, 0x92, FIL_, 0xCC, 0x81, FIL_, - 0xCE, 0x90, FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1, - 0xBF, 0xA2, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xB0, - FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0xA7, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB4, FIL_, - 0x02, 0xCC, 0x88, FIL_, 0xCF, 0x94, FIL_, 0xCC, - 0x81, FIL_, 0xCF, 0x93, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xD0, 0x87, FIL_, 0x02, 0xCC, 0x86, FIL_, - 0xD3, 0x90, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x92, - FIL_, 0x01, 0xCC, 0x81, FIL_, 0xD0, 0x83, FIL_, - 0x03, 0xCC, 0x86, FIL_, 0xD3, 0x96, FIL_, 0xCC, - 0x80, FIL_, 0xD0, 0x80, FIL_, 0xCC, 0x88, FIL_, - 0xD0, 0x81, FIL_, 0x02, 0xCC, 0x88, FIL_, 0xD3, - 0x9C, FIL_, 0xCC, 0x86, FIL_, 0xD3, 0x81, FIL_, - 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9E, FIL_, 0x04, - 0xCC, 0x80, FIL_, 0xD0, 0x8D, FIL_, 0xCC, 0x88, - FIL_, 0xD3, 0xA4, FIL_, 0xCC, 0x86, FIL_, 0xD0, - 0x99, FIL_, 0xCC, 0x84, FIL_, 0xD3, 0xA2, FIL_, - 0x01, 0xCC, 0x81, FIL_, 0xD0, 0x8C, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xA6, FIL_, 0x04, 0xCC, - 0x86, FIL_, 0xD0, 0x8E, FIL_, 0xCC, 0x8B, FIL_, - 0xD3, 0xB2, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0xB0, - FIL_, 0xCC, 0x84, FIL_, 0xD3, 0xAE, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xB4, FIL_, 0x01, 0xCC, - 0x88, FIL_, 0xD3, 0xB8, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xD3, 0xAC, FIL_, 0x02, 0xCC, 0x86, FIL_, - 0xD3, 0x91, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x93, - FIL_, 0x01, 0xCC, 0x81, FIL_, 0xD1, 0x93, FIL_, - 0x03, 0xCC, 0x80, FIL_, 0xD1, 0x90, FIL_, 0xCC, - 0x88, FIL_, 0xD1, 0x91, FIL_, 0xCC, 0x86, FIL_, - 0xD3, 0x97, FIL_, 0x02, 0xCC, 0x88, FIL_, 0xD3, - 0x9D, FIL_, 0xCC, 0x86, FIL_, 0xD3, 0x82, FIL_, - 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9F, FIL_, 0x04, - 0xCC, 0x88, FIL_, 0xD3, 0xA5, FIL_, 0xCC, 0x86, - FIL_, 0xD0, 0xB9, FIL_, 0xCC, 0x80, FIL_, 0xD1, - 0x9D, FIL_, 0xCC, 0x84, FIL_, 0xD3, 0xA3, FIL_, - 0x01, 0xCC, 0x81, FIL_, 0xD1, 0x9C, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xA7, FIL_, 0x04, 0xCC, - 0x84, FIL_, 0xD3, 0xAF, FIL_, 0xCC, 0x86, FIL_, - 0xD1, 0x9E, FIL_, 0xCC, 0x8B, FIL_, 0xD3, 0xB3, - FIL_, 0xCC, 0x88, FIL_, 0xD3, 0xB1, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xB5, FIL_, 0x01, 0xCC, - 0x88, FIL_, 0xD3, 0xB9, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xD3, 0xAD, FIL_, 0x01, 0xCC, 0x88, FIL_, - 0xD1, 0x97, FIL_, 0x01, 0xCC, 0x8F, FIL_, 0xD1, - 0xB6, FIL_, 0x01, 0xCC, 0x8F, FIL_, 0xD1, 0xB7, - FIL_, 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9A, FIL_, - 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9B, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xAA, FIL_, 0x01, 0xCC, - 0x88, FIL_, 0xD3, 0xAB, FIL_, 0x03, 0xD9, 0x94, - FIL_, 0xD8, 0xA3, FIL_, 0xD9, 0x93, FIL_, 0xD8, - 0xA2, FIL_, 0xD9, 0x95, FIL_, 0xD8, 0xA5, FIL_, - 0x01, 0xD9, 0x94, FIL_, 0xD8, 0xA4, FIL_, 0x01, - 0xD9, 0x94, FIL_, 0xD8, 0xA6, FIL_, 0x01, 0xD9, - 0x94, FIL_, 0xDB, 0x82, FIL_, 0x01, 0xD9, 0x94, - FIL_, 0xDB, 0x93, FIL_, 0x01, 0xD9, 0x94, FIL_, - 0xDB, 0x80, FIL_, 0x01, 0xE0, 0xA4, 0xBC, FIL_, - 0xE0, 0xA4, 0xA9, FIL_, 0x01, 0xE0, 0xA4, 0xBC, - FIL_, 0xE0, 0xA4, 0xB1, FIL_, 0x01, 0xE0, 0xA4, - 0xBC, FIL_, 0xE0, 0xA4, 0xB4, FIL_, 0x02, 0xE0, - 0xA6, 0xBE, FIL_, 0xE0, 0xA7, 0x8B, FIL_, 0xE0, - 0xA7, 0x97, FIL_, 0xE0, 0xA7, 0x8C, FIL_, 0x03, - 0xE0, 0xAD, 0x97, FIL_, 0xE0, 0xAD, 0x8C, FIL_, - 0xE0, 0xAC, 0xBE, FIL_, 0xE0, 0xAD, 0x8B, FIL_, - 0xE0, 0xAD, 0x96, FIL_, 0xE0, 0xAD, 0x88, FIL_, - 0x01, 0xE0, 0xAF, 0x97, FIL_, 0xE0, 0xAE, 0x94, - FIL_, 0x02, 0xE0, 0xAE, 0xBE, FIL_, 0xE0, 0xAF, - 0x8A, FIL_, 0xE0, 0xAF, 0x97, FIL_, 0xE0, 0xAF, - 0x8C, FIL_, 0x01, 0xE0, 0xAE, 0xBE, FIL_, 0xE0, - 0xAF, 0x8B, FIL_, 0x01, 0xE0, 0xB1, 0x96, FIL_, - 0xE0, 0xB1, 0x88, FIL_, 0x01, 0xE0, 0xB3, 0x95, - FIL_, 0xE0, 0xB3, 0x80, FIL_, 0x03, 0xE0, 0xB3, - 0x95, FIL_, 0xE0, 0xB3, 0x87, FIL_, 0xE0, 0xB3, - 0x82, FIL_, 0xE0, 0xB3, 0x8A, FIL_, 0xE0, 0xB3, - 0x96, FIL_, 0xE0, 0xB3, 0x88, FIL_, 0x01, 0xE0, - 0xB3, 0x95, FIL_, 0xE0, 0xB3, 0x8B, FIL_, 0x02, - 0xE0, 0xB4, 0xBE, FIL_, 0xE0, 0xB5, 0x8A, FIL_, - 0xE0, 0xB5, 0x97, FIL_, 0xE0, 0xB5, 0x8C, FIL_, - 0x01, 0xE0, 0xB4, 0xBE, FIL_, 0xE0, 0xB5, 0x8B, - FIL_, 0x03, 0xE0, 0xB7, 0x8F, FIL_, 0xE0, 0xB7, - 0x9C, FIL_, 0xE0, 0xB7, 0x8A, FIL_, 0xE0, 0xB7, - 0x9A, FIL_, 0xE0, 0xB7, 0x9F, FIL_, 0xE0, 0xB7, - 0x9E, FIL_, 0x01, 0xE0, 0xB7, 0x8A, FIL_, 0xE0, - 0xB7, 0x9D, FIL_, 0x01, 0xE1, 0x80, 0xAE, FIL_, - 0xE1, 0x80, 0xA6, FIL_, 0x01, 0xCC, 0x84, FIL_, - 0xE1, 0xB8, 0xB8, FIL_, 0x01, 0xCC, 0x84, FIL_, - 0xE1, 0xB8, 0xB9, FIL_, 0x01, 0xCC, 0x84, FIL_, - 0xE1, 0xB9, 0x9C, FIL_, 0x01, 0xCC, 0x84, FIL_, - 0xE1, 0xB9, 0x9D, FIL_, 0x01, 0xCC, 0x87, FIL_, - 0xE1, 0xB9, 0xA8, FIL_, 0x01, 0xCC, 0x87, FIL_, - 0xE1, 0xB9, 0xA9, FIL_, 0x02, 0xCC, 0x86, FIL_, - 0xE1, 0xBA, 0xB6, FIL_, 0xCC, 0x82, FIL_, 0xE1, - 0xBA, 0xAC, FIL_, 0x02, 0xCC, 0x86, FIL_, 0xE1, - 0xBA, 0xB7, FIL_, 0xCC, 0x82, FIL_, 0xE1, 0xBA, - 0xAD, FIL_, 0x01, 0xCC, 0x82, FIL_, 0xE1, 0xBB, - 0x86, FIL_, 0x01, 0xCC, 0x82, FIL_, 0xE1, 0xBB, - 0x87, FIL_, 0x01, 0xCC, 0x82, FIL_, 0xE1, 0xBB, - 0x98, FIL_, 0x01, 0xCC, 0x82, FIL_, 0xE1, 0xBB, - 0x99, FIL_, 0x04, 0xCC, 0x80, FIL_, 0xE1, 0xBC, - 0x82, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x84, - FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x80, FIL_, - 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0x86, FIL_, 0x04, - 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0x87, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBC, 0x83, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xBC, 0x85, FIL_, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x81, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x82, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x83, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x84, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x85, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x86, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x87, FIL_, 0x04, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x88, FIL_, 0xCC, 0x80, FIL_, 0xE1, - 0xBC, 0x8A, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBC, - 0x8E, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x8C, - FIL_, 0x04, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x8D, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x8B, FIL_, - 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0x8F, FIL_, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x89, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x8A, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x8B, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x8C, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x8D, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x8E, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x8F, FIL_, 0x02, 0xCC, - 0x80, FIL_, 0xE1, 0xBC, 0x92, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xBC, 0x94, FIL_, 0x02, 0xCC, 0x80, - FIL_, 0xE1, 0xBC, 0x93, FIL_, 0xCC, 0x81, FIL_, - 0xE1, 0xBC, 0x95, FIL_, 0x02, 0xCC, 0x80, FIL_, - 0xE1, 0xBC, 0x9A, FIL_, 0xCC, 0x81, FIL_, 0xE1, - 0xBC, 0x9C, FIL_, 0x02, 0xCC, 0x80, FIL_, 0xE1, - 0xBC, 0x9B, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, - 0x9D, FIL_, 0x04, 0xCD, 0x82, FIL_, 0xE1, 0xBC, - 0xA6, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x90, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xA4, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xA2, FIL_, 0x04, - 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xA3, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xBC, 0xA5, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBC, 0xA7, FIL_, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x91, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x92, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x93, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x94, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x95, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x96, FIL_, 0x01, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0x97, FIL_, 0x04, 0xCD, 0x82, FIL_, - 0xE1, 0xBC, 0xAE, FIL_, 0xCC, 0x81, FIL_, 0xE1, - 0xBC, 0xAC, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, - 0x98, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xAA, - FIL_, 0x04, 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xAF, - FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x99, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xAD, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBC, 0xAB, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x9A, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x9B, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x9C, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x9D, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x9E, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0x9F, FIL_, 0x03, 0xCC, - 0x81, FIL_, 0xE1, 0xBC, 0xB4, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBC, 0xB6, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBC, 0xB2, FIL_, 0x03, 0xCC, 0x81, FIL_, - 0xE1, 0xBC, 0xB5, FIL_, 0xCD, 0x82, FIL_, 0xE1, - 0xBC, 0xB7, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, - 0xB3, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xBC, - 0xBC, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xBA, - FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xBE, FIL_, - 0x03, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xBB, FIL_, - 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xBF, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xBC, 0xBD, FIL_, 0x02, 0xCC, - 0x80, FIL_, 0xE1, 0xBD, 0x82, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xBD, 0x84, FIL_, 0x02, 0xCC, 0x80, - FIL_, 0xE1, 0xBD, 0x83, FIL_, 0xCC, 0x81, FIL_, - 0xE1, 0xBD, 0x85, FIL_, 0x02, 0xCC, 0x81, FIL_, - 0xE1, 0xBD, 0x8C, FIL_, 0xCC, 0x80, FIL_, 0xE1, - 0xBD, 0x8A, FIL_, 0x02, 0xCC, 0x81, FIL_, 0xE1, - 0xBD, 0x8D, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, - 0x8B, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xBD, - 0x94, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0x96, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x92, FIL_, - 0x03, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0x97, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x95, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBD, 0x93, FIL_, 0x03, 0xCC, - 0x81, FIL_, 0xE1, 0xBD, 0x9D, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBD, 0x9F, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBD, 0x9B, FIL_, 0x04, 0xCC, 0x81, FIL_, - 0xE1, 0xBD, 0xA4, FIL_, 0xCC, 0x80, FIL_, 0xE1, - 0xBD, 0xA2, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD, - 0xA6, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA0, - FIL_, 0x04, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0xA7, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0xA5, FIL_, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA1, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBD, 0xA3, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xA2, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xA3, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xA4, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xA5, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xA6, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xA7, FIL_, 0x04, 0xCC, - 0x81, FIL_, 0xE1, 0xBD, 0xAC, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBD, 0xAA, FIL_, 0xCD, 0x82, FIL_, - 0xE1, 0xBD, 0xAE, FIL_, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xA8, FIL_, 0x04, 0xCC, 0x81, FIL_, 0xE1, - 0xBD, 0xAD, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, - 0xA9, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0xAF, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xAB, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAA, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAB, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAC, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAD, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAE, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xAF, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xB2, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0x82, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB2, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xB7, FIL_, - 0x03, 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0x8F, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0x8D, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xBF, 0x8E, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBF, 0x87, FIL_, 0x01, 0xCD, - 0x85, FIL_, 0xE1, 0xBF, 0xB7, FIL_, 0x03, 0xCC, - 0x80, FIL_, 0xE1, 0xBF, 0x9D, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBF, 0x9F, FIL_, 0xCC, 0x81, FIL_, - 0xE1, 0xBF, 0x9E, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x86, 0x9A, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x86, 0x9B, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x86, 0xAE, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x87, 0x8D, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x87, 0x8F, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x87, 0x8E, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x88, 0x84, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x88, 0x89, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x88, 0x8C, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x88, 0xA4, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x88, 0xA6, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0x81, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0x84, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0x87, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0x89, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0xAD, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0xA2, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0xB0, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0xB1, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0xB4, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0xB5, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0xB8, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x89, 0xB9, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0x80, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0x81, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8B, 0xA0, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8B, 0xA1, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0x84, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0x85, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0x88, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0x89, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8B, 0xA2, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8B, 0xA3, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0xAC, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0xAD, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0xAE, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8A, 0xAF, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8B, 0xAA, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8B, 0xAB, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8B, 0xAC, FIL_, 0x01, 0xCC, 0xB8, FIL_, - 0xE2, 0x8B, 0xAD, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x82, 0x94, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x81, 0x8C, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x81, 0x8E, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x90, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x92, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, - 0x94, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x81, 0x96, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x81, 0x98, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x81, 0x9A, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x81, 0x9C, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x81, 0x9E, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xA0, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xA2, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, - 0xA5, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x81, 0xA7, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x81, 0xA9, FIL_, 0x02, 0xE3, 0x82, 0x9A, - FIL_, 0xE3, 0x81, 0xB1, FIL_, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x81, 0xB0, FIL_, 0x02, 0xE3, 0x82, - 0x9A, FIL_, 0xE3, 0x81, 0xB4, FIL_, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x81, 0xB3, FIL_, 0x02, 0xE3, - 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xB7, FIL_, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x81, 0xB6, FIL_, 0x02, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xB9, FIL_, - 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xBA, FIL_, - 0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xBC, - FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xBD, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, - 0x9E, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x83, 0xB4, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x82, 0xAC, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x82, 0xAE, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x82, 0xB0, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x82, 0xB2, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xB4, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xB6, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, - 0xB8, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x82, 0xBA, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x82, 0xBC, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x82, 0xBE, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x83, 0x80, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x83, 0x82, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x85, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x87, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, - 0x89, FIL_, 0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x83, 0x90, FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, - 0x83, 0x91, FIL_, 0x02, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x83, 0x93, FIL_, 0xE3, 0x82, 0x9A, FIL_, - 0xE3, 0x83, 0x94, FIL_, 0x02, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x83, 0x96, FIL_, 0xE3, 0x82, 0x9A, - FIL_, 0xE3, 0x83, 0x97, FIL_, 0x02, 0xE3, 0x82, - 0x9A, FIL_, 0xE3, 0x83, 0x9A, FIL_, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x83, 0x99, FIL_, 0x02, 0xE3, - 0x82, 0x9A, FIL_, 0xE3, 0x83, 0x9D, FIL_, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x83, 0x9C, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0xB7, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0xB8, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, - 0xB9, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x83, 0xBA, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x83, 0xBE, FIL_, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - }, - { - 0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAE, FIL_, - 0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xA0, FIL_, - 0x01, 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAF, FIL_, - 0x10, 0xCC, 0xA5, FIL_, 0xE1, 0xB8, 0x80, FIL_, - 0xCC, 0x87, FIL_, 0xC8, 0xA6, FIL_, 0xCC, 0x83, - FIL_, 0xC3, 0x83, FIL_, 0xCC, 0x91, FIL_, 0xC8, - 0x82, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x80, FIL_, - 0xCC, 0x8A, FIL_, 0xC3, 0x85, FIL_, 0xCC, 0x88, - FIL_, 0xC3, 0x84, FIL_, 0xCC, 0x89, FIL_, 0xE1, - 0xBA, 0xA2, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, - 0xA0, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x8D, FIL_, - 0xCC, 0x80, FIL_, 0xC3, 0x80, FIL_, 0xCC, 0x81, - FIL_, 0xC3, 0x81, FIL_, 0xCC, 0x82, FIL_, 0xC3, - 0x82, FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x84, FIL_, - 0xCC, 0x86, FIL_, 0xC4, 0x82, FIL_, 0xCC, 0x84, - FIL_, 0xC4, 0x80, FIL_, 0x03, 0xCC, 0xB1, FIL_, - 0xE1, 0xB8, 0x86, FIL_, 0xCC, 0x87, FIL_, 0xE1, - 0xB8, 0x82, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, - 0x84, FIL_, 0x05, 0xCC, 0xA7, FIL_, 0xC3, 0x87, - FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x8C, FIL_, 0xCC, - 0x81, FIL_, 0xC4, 0x86, FIL_, 0xCC, 0x82, FIL_, - 0xC4, 0x88, FIL_, 0xCC, 0x87, FIL_, 0xC4, 0x8A, - FIL_, 0x06, 0xCC, 0xA7, FIL_, 0xE1, 0xB8, 0x90, - FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x8E, FIL_, 0xCC, - 0xB1, FIL_, 0xE1, 0xB8, 0x8E, FIL_, 0xCC, 0xAD, - FIL_, 0xE1, 0xB8, 0x92, FIL_, 0xCC, 0xA3, FIL_, - 0xE1, 0xB8, 0x8C, FIL_, 0xCC, 0x87, FIL_, 0xE1, - 0xB8, 0x8A, FIL_, 0x11, 0xCC, 0x84, FIL_, 0xC4, - 0x92, FIL_, 0xCC, 0x86, FIL_, 0xC4, 0x94, FIL_, - 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0xB8, FIL_, 0xCC, - 0x91, FIL_, 0xC8, 0x86, FIL_, 0xCC, 0x82, FIL_, - 0xC3, 0x8A, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x84, - FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0x98, FIL_, - 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xBA, FIL_, 0xCC, - 0xA7, FIL_, 0xC8, 0xA8, FIL_, 0xCC, 0x8C, FIL_, - 0xC4, 0x9A, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x88, - FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x98, FIL_, 0xCC, - 0x83, FIL_, 0xE1, 0xBA, 0xBC, FIL_, 0xCC, 0x87, - FIL_, 0xC4, 0x96, FIL_, 0xCC, 0x81, FIL_, 0xC3, - 0x89, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x8B, FIL_, - 0xCC, 0xB0, FIL_, 0xE1, 0xB8, 0x9A, FIL_, 0x01, - 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x9E, FIL_, 0x07, - 0xCC, 0x8C, FIL_, 0xC7, 0xA6, FIL_, 0xCC, 0x86, - FIL_, 0xC4, 0x9E, FIL_, 0xCC, 0x82, FIL_, 0xC4, - 0x9C, FIL_, 0xCC, 0xA7, FIL_, 0xC4, 0xA2, FIL_, - 0xCC, 0x84, FIL_, 0xE1, 0xB8, 0xA0, FIL_, 0xCC, - 0x81, FIL_, 0xC7, 0xB4, FIL_, 0xCC, 0x87, FIL_, - 0xC4, 0xA0, FIL_, 0x07, 0xCC, 0x87, FIL_, 0xE1, - 0xB8, 0xA2, FIL_, 0xCC, 0xA7, FIL_, 0xE1, 0xB8, - 0xA8, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0xA4, FIL_, - 0xCC, 0x88, FIL_, 0xE1, 0xB8, 0xA6, FIL_, 0xCC, - 0x8C, FIL_, 0xC8, 0x9E, FIL_, 0xCC, 0xAE, FIL_, - 0xE1, 0xB8, 0xAA, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xB8, 0xA4, FIL_, 0x0F, 0xCC, 0xB0, FIL_, 0xE1, - 0xB8, 0xAC, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x8F, - FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x8C, FIL_, 0xCC, - 0x89, FIL_, 0xE1, 0xBB, 0x88, FIL_, 0xCC, 0xA3, - FIL_, 0xE1, 0xBB, 0x8A, FIL_, 0xCC, 0x91, FIL_, - 0xC8, 0x8A, FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x8F, - FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x8E, FIL_, 0xCC, - 0x81, FIL_, 0xC3, 0x8D, FIL_, 0xCC, 0x83, FIL_, - 0xC4, 0xA8, FIL_, 0xCC, 0x87, FIL_, 0xC4, 0xB0, - FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x88, FIL_, 0xCC, - 0xA8, FIL_, 0xC4, 0xAE, FIL_, 0xCC, 0x86, FIL_, - 0xC4, 0xAC, FIL_, 0xCC, 0x84, FIL_, 0xC4, 0xAA, - FIL_, 0x01, 0xCC, 0x82, FIL_, 0xC4, 0xB4, FIL_, - 0x05, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xB0, FIL_, - 0xCC, 0x8C, FIL_, 0xC7, 0xA8, FIL_, 0xCC, 0xB1, - FIL_, 0xE1, 0xB8, 0xB4, FIL_, 0xCC, 0xA7, FIL_, - 0xC4, 0xB6, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, - 0xB2, FIL_, 0x06, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, - 0xB6, FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0xBD, FIL_, - 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0xBC, FIL_, 0xCC, - 0xB1, FIL_, 0xE1, 0xB8, 0xBA, FIL_, 0xCC, 0xA7, - FIL_, 0xC4, 0xBB, FIL_, 0xCC, 0x81, FIL_, 0xC4, - 0xB9, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xB8, - 0xBE, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x80, - FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x82, FIL_, - 0x09, 0xCC, 0x83, FIL_, 0xC3, 0x91, FIL_, 0xCC, - 0x81, FIL_, 0xC5, 0x83, FIL_, 0xCC, 0xA7, FIL_, - 0xC5, 0x85, FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0x87, - FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x84, FIL_, - 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x86, FIL_, 0xCC, - 0xB1, FIL_, 0xE1, 0xB9, 0x88, FIL_, 0xCC, 0xAD, - FIL_, 0xE1, 0xB9, 0x8A, FIL_, 0xCC, 0x80, FIL_, - 0xC7, 0xB8, FIL_, 0x10, 0xCC, 0x89, FIL_, 0xE1, - 0xBB, 0x8E, FIL_, 0xCC, 0x84, FIL_, 0xC5, 0x8C, - FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x94, FIL_, 0xCC, - 0x86, FIL_, 0xC5, 0x8E, FIL_, 0xCC, 0x83, FIL_, - 0xC3, 0x95, FIL_, 0xCC, 0x8B, FIL_, 0xC5, 0x90, - FIL_, 0xCC, 0x88, FIL_, 0xC3, 0x96, FIL_, 0xCC, - 0x9B, FIL_, 0xC6, 0xA0, FIL_, 0xCC, 0x91, FIL_, - 0xC8, 0x8E, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x91, - FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x8C, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xBB, 0x8C, FIL_, 0xCC, 0x80, - FIL_, 0xC3, 0x92, FIL_, 0xCC, 0xA8, FIL_, 0xC7, - 0xAA, FIL_, 0xCC, 0x87, FIL_, 0xC8, 0xAE, FIL_, - 0xCC, 0x81, FIL_, 0xC3, 0x93, FIL_, 0x02, 0xCC, - 0x87, FIL_, 0xE1, 0xB9, 0x96, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0x94, FIL_, 0x08, 0xCC, 0xA7, - FIL_, 0xC5, 0x96, FIL_, 0xCC, 0x8C, FIL_, 0xC5, - 0x98, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x92, FIL_, - 0xCC, 0x8F, FIL_, 0xC8, 0x90, FIL_, 0xCC, 0x81, - FIL_, 0xC5, 0x94, FIL_, 0xCC, 0x87, FIL_, 0xE1, - 0xB9, 0x98, FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB9, - 0x9E, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x9A, - FIL_, 0x07, 0xCC, 0xA6, FIL_, 0xC8, 0x98, FIL_, - 0xCC, 0x81, FIL_, 0xC5, 0x9A, FIL_, 0xCC, 0x82, - FIL_, 0xC5, 0x9C, FIL_, 0xCC, 0xA7, FIL_, 0xC5, - 0x9E, FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0xA0, FIL_, - 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xA0, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xB9, 0xA2, FIL_, 0x07, 0xCC, - 0xA6, FIL_, 0xC8, 0x9A, FIL_, 0xCC, 0x87, FIL_, - 0xE1, 0xB9, 0xAA, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xB9, 0xAC, FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB9, - 0xAE, FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0xB0, - FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0xA2, FIL_, 0xCC, - 0x8C, FIL_, 0xC5, 0xA4, FIL_, 0x13, 0xCC, 0x8A, - FIL_, 0xC5, 0xAE, FIL_, 0xCC, 0x88, FIL_, 0xC3, - 0x9C, FIL_, 0xCC, 0x8B, FIL_, 0xC5, 0xB0, FIL_, - 0xCC, 0xAD, FIL_, 0xE1, 0xB9, 0xB6, FIL_, 0xCC, - 0xA8, FIL_, 0xC5, 0xB2, FIL_, 0xCC, 0x8C, FIL_, - 0xC7, 0x93, FIL_, 0xCC, 0x80, FIL_, 0xC3, 0x99, - FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x94, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xBB, 0xA4, FIL_, 0xCC, 0xA4, - FIL_, 0xE1, 0xB9, 0xB2, FIL_, 0xCC, 0x81, FIL_, - 0xC3, 0x9A, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0x9B, - FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB9, 0xB4, FIL_, - 0xCC, 0x83, FIL_, 0xC5, 0xA8, FIL_, 0xCC, 0x89, - FIL_, 0xE1, 0xBB, 0xA6, FIL_, 0xCC, 0x84, FIL_, - 0xC5, 0xAA, FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x96, - FIL_, 0xCC, 0x86, FIL_, 0xC5, 0xAC, FIL_, 0xCC, - 0x9B, FIL_, 0xC6, 0xAF, FIL_, 0x02, 0xCC, 0xA3, - FIL_, 0xE1, 0xB9, 0xBE, FIL_, 0xCC, 0x83, FIL_, - 0xE1, 0xB9, 0xBC, FIL_, 0x06, 0xCC, 0x88, FIL_, - 0xE1, 0xBA, 0x84, FIL_, 0xCC, 0x81, FIL_, 0xE1, - 0xBA, 0x82, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, - 0x80, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x88, - FIL_, 0xCC, 0x82, FIL_, 0xC5, 0xB4, FIL_, 0xCC, - 0x87, FIL_, 0xE1, 0xBA, 0x86, FIL_, 0x02, 0xCC, - 0x88, FIL_, 0xE1, 0xBA, 0x8C, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xBA, 0x8A, FIL_, 0x09, 0xCC, 0x89, - FIL_, 0xE1, 0xBB, 0xB6, FIL_, 0xCC, 0xA3, FIL_, - 0xE1, 0xBB, 0xB4, FIL_, 0xCC, 0x80, FIL_, 0xE1, - 0xBB, 0xB2, FIL_, 0xCC, 0x88, FIL_, 0xC5, 0xB8, - FIL_, 0xCC, 0x81, FIL_, 0xC3, 0x9D, FIL_, 0xCC, - 0x83, FIL_, 0xE1, 0xBB, 0xB8, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xBA, 0x8E, FIL_, 0xCC, 0x84, FIL_, - 0xC8, 0xB2, FIL_, 0xCC, 0x82, FIL_, 0xC5, 0xB6, - FIL_, 0x06, 0xCC, 0x82, FIL_, 0xE1, 0xBA, 0x90, - FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0x92, FIL_, - 0xCC, 0xB1, FIL_, 0xE1, 0xBA, 0x94, FIL_, 0xCC, - 0x8C, FIL_, 0xC5, 0xBD, FIL_, 0xCC, 0x87, FIL_, - 0xC5, 0xBB, FIL_, 0xCC, 0x81, FIL_, 0xC5, 0xB9, - FIL_, 0x10, 0xCC, 0xA3, FIL_, 0xE1, 0xBA, 0xA1, - FIL_, 0xCC, 0xA8, FIL_, 0xC4, 0x85, FIL_, 0xCC, - 0x81, FIL_, 0xC3, 0xA1, FIL_, 0xCC, 0x82, FIL_, - 0xC3, 0xA2, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, - 0xA3, FIL_, 0xCC, 0x83, FIL_, 0xC3, 0xA3, FIL_, - 0xCC, 0x8C, FIL_, 0xC7, 0x8E, FIL_, 0xCC, 0x8A, - FIL_, 0xC3, 0xA5, FIL_, 0xCC, 0x88, FIL_, 0xC3, - 0xA4, FIL_, 0xCC, 0x87, FIL_, 0xC8, 0xA7, FIL_, - 0xCC, 0x91, FIL_, 0xC8, 0x83, FIL_, 0xCC, 0xA5, - FIL_, 0xE1, 0xB8, 0x81, FIL_, 0xCC, 0x84, FIL_, - 0xC4, 0x81, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x81, - FIL_, 0xCC, 0x86, FIL_, 0xC4, 0x83, FIL_, 0xCC, - 0x80, FIL_, 0xC3, 0xA0, FIL_, 0x03, 0xCC, 0xA3, - FIL_, 0xE1, 0xB8, 0x85, FIL_, 0xCC, 0x87, FIL_, - 0xE1, 0xB8, 0x83, FIL_, 0xCC, 0xB1, FIL_, 0xE1, - 0xB8, 0x87, FIL_, 0x05, 0xCC, 0x87, FIL_, 0xC4, - 0x8B, FIL_, 0xCC, 0x8C, FIL_, 0xC4, 0x8D, FIL_, - 0xCC, 0x82, FIL_, 0xC4, 0x89, FIL_, 0xCC, 0x81, - FIL_, 0xC4, 0x87, FIL_, 0xCC, 0xA7, FIL_, 0xC3, - 0xA7, FIL_, 0x06, 0xCC, 0x87, FIL_, 0xE1, 0xB8, - 0x8B, FIL_, 0xCC, 0xA7, FIL_, 0xE1, 0xB8, 0x91, - FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0x8F, FIL_, - 0xCC, 0xA3, FIL_, 0xE1, 0xB8, 0x8D, FIL_, 0xCC, - 0x8C, FIL_, 0xC4, 0x8F, FIL_, 0xCC, 0xAD, FIL_, - 0xE1, 0xB8, 0x93, FIL_, 0x11, 0xCC, 0x80, FIL_, - 0xC3, 0xA8, FIL_, 0xCC, 0x81, FIL_, 0xC3, 0xA9, - FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xAA, FIL_, 0xCC, - 0x88, FIL_, 0xC3, 0xAB, FIL_, 0xCC, 0x84, FIL_, - 0xC4, 0x93, FIL_, 0xCC, 0x86, FIL_, 0xC4, 0x95, - FIL_, 0xCC, 0x87, FIL_, 0xC4, 0x97, FIL_, 0xCC, - 0xA8, FIL_, 0xC4, 0x99, FIL_, 0xCC, 0x8C, FIL_, - 0xC4, 0x9B, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x85, - FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x87, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xBA, 0xB9, FIL_, 0xCC, 0xA7, - FIL_, 0xC8, 0xA9, FIL_, 0xCC, 0x83, FIL_, 0xE1, - 0xBA, 0xBD, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, - 0xBB, FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0x99, - FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB8, 0x9B, FIL_, - 0x01, 0xCC, 0x87, FIL_, 0xE1, 0xB8, 0x9F, FIL_, - 0x07, 0xCC, 0x86, FIL_, 0xC4, 0x9F, FIL_, 0xCC, - 0x87, FIL_, 0xC4, 0xA1, FIL_, 0xCC, 0x82, FIL_, - 0xC4, 0x9D, FIL_, 0xCC, 0x84, FIL_, 0xE1, 0xB8, - 0xA1, FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0xA7, FIL_, - 0xCC, 0xA7, FIL_, 0xC4, 0xA3, FIL_, 0xCC, 0x81, - FIL_, 0xC7, 0xB5, FIL_, 0x08, 0xCC, 0xA7, FIL_, - 0xE1, 0xB8, 0xA9, FIL_, 0xCC, 0xB1, FIL_, 0xE1, - 0xBA, 0x96, FIL_, 0xCC, 0x8C, FIL_, 0xC8, 0x9F, - FIL_, 0xCC, 0xAE, FIL_, 0xE1, 0xB8, 0xAB, FIL_, - 0xCC, 0x88, FIL_, 0xE1, 0xB8, 0xA7, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xB8, 0xA5, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xB8, 0xA3, FIL_, 0xCC, 0x82, FIL_, - 0xC4, 0xA5, FIL_, 0x0E, 0xCC, 0x88, FIL_, 0xC3, - 0xAF, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x89, - FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0x8B, FIL_, - 0xCC, 0x82, FIL_, 0xC3, 0xAE, FIL_, 0xCC, 0x81, - FIL_, 0xC3, 0xAD, FIL_, 0xCC, 0x80, FIL_, 0xC3, - 0xAC, FIL_, 0xCC, 0x83, FIL_, 0xC4, 0xA9, FIL_, - 0xCC, 0x84, FIL_, 0xC4, 0xAB, FIL_, 0xCC, 0x86, - FIL_, 0xC4, 0xAD, FIL_, 0xCC, 0xA8, FIL_, 0xC4, - 0xAF, FIL_, 0xCC, 0xB0, FIL_, 0xE1, 0xB8, 0xAD, - FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x90, FIL_, 0xCC, - 0x91, FIL_, 0xC8, 0x8B, FIL_, 0xCC, 0x8F, FIL_, - 0xC8, 0x89, FIL_, 0x02, 0xCC, 0x8C, FIL_, 0xC7, - 0xB0, FIL_, 0xCC, 0x82, FIL_, 0xC4, 0xB5, FIL_, - 0x05, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0xB5, FIL_, - 0xCC, 0xA7, FIL_, 0xC4, 0xB7, FIL_, 0xCC, 0x8C, - FIL_, 0xC7, 0xA9, FIL_, 0xCC, 0x81, FIL_, 0xE1, - 0xB8, 0xB1, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, - 0xB3, FIL_, 0x06, 0xCC, 0xA3, FIL_, 0xE1, 0xB8, - 0xB7, FIL_, 0xCC, 0xAD, FIL_, 0xE1, 0xB8, 0xBD, - FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB8, 0xBB, FIL_, - 0xCC, 0xA7, FIL_, 0xC4, 0xBC, FIL_, 0xCC, 0x81, - FIL_, 0xC4, 0xBA, FIL_, 0xCC, 0x8C, FIL_, 0xC4, - 0xBE, FIL_, 0x03, 0xCC, 0x87, FIL_, 0xE1, 0xB9, - 0x81, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x83, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xBF, FIL_, - 0x09, 0xCC, 0x80, FIL_, 0xC7, 0xB9, FIL_, 0xCC, - 0xAD, FIL_, 0xE1, 0xB9, 0x8B, FIL_, 0xCC, 0x83, - FIL_, 0xC3, 0xB1, FIL_, 0xCC, 0x81, FIL_, 0xC5, - 0x84, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0x87, - FIL_, 0xCC, 0xB1, FIL_, 0xE1, 0xB9, 0x89, FIL_, - 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0x85, FIL_, 0xCC, - 0xA7, FIL_, 0xC5, 0x86, FIL_, 0xCC, 0x8C, FIL_, - 0xC5, 0x88, FIL_, 0x10, 0xCC, 0xA3, FIL_, 0xE1, - 0xBB, 0x8D, FIL_, 0xCC, 0x87, FIL_, 0xC8, 0xAF, - FIL_, 0xCC, 0x80, FIL_, 0xC3, 0xB2, FIL_, 0xCC, - 0x91, FIL_, 0xC8, 0x8F, FIL_, 0xCC, 0x89, FIL_, - 0xE1, 0xBB, 0x8F, FIL_, 0xCC, 0x88, FIL_, 0xC3, - 0xB6, FIL_, 0xCC, 0x83, FIL_, 0xC3, 0xB5, FIL_, - 0xCC, 0x81, FIL_, 0xC3, 0xB3, FIL_, 0xCC, 0x8C, - FIL_, 0xC7, 0x92, FIL_, 0xCC, 0xA8, FIL_, 0xC7, - 0xAB, FIL_, 0xCC, 0x9B, FIL_, 0xC6, 0xA1, FIL_, - 0xCC, 0x84, FIL_, 0xC5, 0x8D, FIL_, 0xCC, 0x86, - FIL_, 0xC5, 0x8F, FIL_, 0xCC, 0x8B, FIL_, 0xC5, - 0x91, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xB4, FIL_, - 0xCC, 0x8F, FIL_, 0xC8, 0x8D, FIL_, 0x02, 0xCC, - 0x87, FIL_, 0xE1, 0xB9, 0x97, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0x95, FIL_, 0x08, 0xCC, 0x8C, - FIL_, 0xC5, 0x99, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xB9, 0x9B, FIL_, 0xCC, 0x81, FIL_, 0xC5, 0x95, - FIL_, 0xCC, 0xA7, FIL_, 0xC5, 0x97, FIL_, 0xCC, - 0xB1, FIL_, 0xE1, 0xB9, 0x9F, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0x99, FIL_, 0xCC, 0x91, FIL_, - 0xC8, 0x93, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x91, - FIL_, 0x07, 0xCC, 0xA7, FIL_, 0xC5, 0x9F, FIL_, - 0xCC, 0x82, FIL_, 0xC5, 0x9D, FIL_, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA1, FIL_, 0xCC, 0xA6, FIL_, - 0xC8, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xC5, 0x9B, - FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, 0xA3, FIL_, - 0xCC, 0x8C, FIL_, 0xC5, 0xA1, FIL_, 0x08, 0xCC, - 0xA6, FIL_, 0xC8, 0x9B, FIL_, 0xCC, 0xAD, FIL_, - 0xE1, 0xB9, 0xB1, FIL_, 0xCC, 0xB1, FIL_, 0xE1, - 0xB9, 0xAF, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xB9, - 0xAD, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xAB, - FIL_, 0xCC, 0x8C, FIL_, 0xC5, 0xA5, FIL_, 0xCC, - 0xA7, FIL_, 0xC5, 0xA3, FIL_, 0xCC, 0x88, FIL_, - 0xE1, 0xBA, 0x97, FIL_, 0x13, 0xCC, 0x8A, FIL_, - 0xC5, 0xAF, FIL_, 0xCC, 0x8F, FIL_, 0xC8, 0x95, - FIL_, 0xCC, 0x8C, FIL_, 0xC7, 0x94, FIL_, 0xCC, - 0x80, FIL_, 0xC3, 0xB9, FIL_, 0xCC, 0x9B, FIL_, - 0xC6, 0xB0, FIL_, 0xCC, 0x82, FIL_, 0xC3, 0xBB, - FIL_, 0xCC, 0x81, FIL_, 0xC3, 0xBA, FIL_, 0xCC, - 0x88, FIL_, 0xC3, 0xBC, FIL_, 0xCC, 0x83, FIL_, - 0xC5, 0xA9, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, - 0xA7, FIL_, 0xCC, 0x84, FIL_, 0xC5, 0xAB, FIL_, - 0xCC, 0x86, FIL_, 0xC5, 0xAD, FIL_, 0xCC, 0xAD, - FIL_, 0xE1, 0xB9, 0xB7, FIL_, 0xCC, 0x8B, FIL_, - 0xC5, 0xB1, FIL_, 0xCC, 0xA8, FIL_, 0xC5, 0xB3, - FIL_, 0xCC, 0x91, FIL_, 0xC8, 0x97, FIL_, 0xCC, - 0xA4, FIL_, 0xE1, 0xB9, 0xB3, FIL_, 0xCC, 0xA3, - FIL_, 0xE1, 0xBB, 0xA5, FIL_, 0xCC, 0xB0, FIL_, - 0xE1, 0xB9, 0xB5, FIL_, 0x02, 0xCC, 0x83, FIL_, - 0xE1, 0xB9, 0xBD, FIL_, 0xCC, 0xA3, FIL_, 0xE1, - 0xB9, 0xBF, FIL_, 0x07, 0xCC, 0x8A, FIL_, 0xE1, - 0xBA, 0x98, FIL_, 0xCC, 0x87, FIL_, 0xE1, 0xBA, - 0x87, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0x83, - FIL_, 0xCC, 0x82, FIL_, 0xC5, 0xB5, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBA, 0x81, FIL_, 0xCC, 0xA3, - FIL_, 0xE1, 0xBA, 0x89, FIL_, 0xCC, 0x88, FIL_, - 0xE1, 0xBA, 0x85, FIL_, 0x02, 0xCC, 0x87, FIL_, - 0xE1, 0xBA, 0x8B, FIL_, 0xCC, 0x88, FIL_, 0xE1, - 0xBA, 0x8D, FIL_, 0x0A, 0xCC, 0x87, FIL_, 0xE1, - 0xBA, 0x8F, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, - 0xB5, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0xB7, - FIL_, 0xCC, 0x8A, FIL_, 0xE1, 0xBA, 0x99, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0xB3, FIL_, 0xCC, - 0x83, FIL_, 0xE1, 0xBB, 0xB9, FIL_, 0xCC, 0x88, - FIL_, 0xC3, 0xBF, FIL_, 0xCC, 0x81, FIL_, 0xC3, - 0xBD, FIL_, 0xCC, 0x84, FIL_, 0xC8, 0xB3, FIL_, - 0xCC, 0x82, FIL_, 0xC5, 0xB7, FIL_, 0x06, 0xCC, - 0xB1, FIL_, 0xE1, 0xBA, 0x95, FIL_, 0xCC, 0xA3, - FIL_, 0xE1, 0xBA, 0x93, FIL_, 0xCC, 0x82, FIL_, - 0xE1, 0xBA, 0x91, FIL_, 0xCC, 0x81, FIL_, 0xC5, - 0xBA, FIL_, 0xCC, 0x87, FIL_, 0xC5, 0xBC, FIL_, - 0xCC, 0x8C, FIL_, 0xC5, 0xBE, FIL_, 0x03, 0xCC, - 0x80, FIL_, 0xE1, 0xBF, 0xAD, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBF, 0x81, FIL_, 0xCC, 0x81, FIL_, - 0xCE, 0x85, FIL_, 0x04, 0xCC, 0x83, FIL_, 0xE1, - 0xBA, 0xAA, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, - 0xA4, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xA8, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBA, 0xA6, FIL_, - 0x01, 0xCC, 0x84, FIL_, 0xC7, 0x9E, FIL_, 0x01, - 0xCC, 0x81, FIL_, 0xC7, 0xBA, FIL_, 0x02, 0xCC, - 0x84, FIL_, 0xC7, 0xA2, FIL_, 0xCC, 0x81, FIL_, - 0xC7, 0xBC, FIL_, 0x01, 0xCC, 0x81, FIL_, 0xE1, - 0xB8, 0x88, FIL_, 0x04, 0xCC, 0x83, FIL_, 0xE1, - 0xBB, 0x84, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBB, - 0x80, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x82, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xBE, FIL_, - 0x01, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0xAE, FIL_, - 0x04, 0xCC, 0x81, FIL_, 0xE1, 0xBB, 0x90, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0x92, FIL_, 0xCC, - 0x89, FIL_, 0xE1, 0xBB, 0x94, FIL_, 0xCC, 0x83, - FIL_, 0xE1, 0xBB, 0x96, FIL_, 0x03, 0xCC, 0x84, - FIL_, 0xC8, 0xAC, FIL_, 0xCC, 0x88, FIL_, 0xE1, - 0xB9, 0x8E, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xB9, - 0x8C, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC8, 0xAA, - FIL_, 0x01, 0xCC, 0x81, FIL_, 0xC7, 0xBE, FIL_, - 0x04, 0xCC, 0x80, FIL_, 0xC7, 0x9B, FIL_, 0xCC, - 0x84, FIL_, 0xC7, 0x95, FIL_, 0xCC, 0x8C, FIL_, - 0xC7, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xC7, 0x97, - FIL_, 0x04, 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xA5, - FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBA, 0xAB, FIL_, - 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xA9, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBA, 0xA7, FIL_, 0x01, 0xCC, - 0x84, FIL_, 0xC7, 0x9F, FIL_, 0x01, 0xCC, 0x81, - FIL_, 0xC7, 0xBB, FIL_, 0x02, 0xCC, 0x81, FIL_, - 0xC7, 0xBD, FIL_, 0xCC, 0x84, FIL_, 0xC7, 0xA3, - FIL_, 0x01, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x89, - FIL_, 0x04, 0xCC, 0x89, FIL_, 0xE1, 0xBB, 0x83, - FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0x85, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0x81, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xBA, 0xBF, FIL_, 0x01, 0xCC, - 0x81, FIL_, 0xE1, 0xB8, 0xAF, FIL_, 0x04, 0xCC, - 0x80, FIL_, 0xE1, 0xBB, 0x93, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xBB, 0x91, FIL_, 0xCC, 0x83, FIL_, - 0xE1, 0xBB, 0x97, FIL_, 0xCC, 0x89, FIL_, 0xE1, - 0xBB, 0x95, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, - 0xB9, 0x8D, FIL_, 0xCC, 0x88, FIL_, 0xE1, 0xB9, - 0x8F, FIL_, 0xCC, 0x84, FIL_, 0xC8, 0xAD, FIL_, - 0x01, 0xCC, 0x84, FIL_, 0xC8, 0xAB, FIL_, 0x01, - 0xCC, 0x81, FIL_, 0xC7, 0xBF, FIL_, 0x04, 0xCC, - 0x8C, FIL_, 0xC7, 0x9A, FIL_, 0xCC, 0x84, FIL_, - 0xC7, 0x96, FIL_, 0xCC, 0x80, FIL_, 0xC7, 0x9C, - FIL_, 0xCC, 0x81, FIL_, 0xC7, 0x98, FIL_, 0x04, - 0xCC, 0x81, FIL_, 0xE1, 0xBA, 0xAE, FIL_, 0xCC, - 0x83, FIL_, 0xE1, 0xBA, 0xB4, FIL_, 0xCC, 0x89, - FIL_, 0xE1, 0xBA, 0xB2, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBA, 0xB0, FIL_, 0x04, 0xCC, 0x83, FIL_, - 0xE1, 0xBA, 0xB5, FIL_, 0xCC, 0x80, FIL_, 0xE1, - 0xBA, 0xB1, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBA, - 0xAF, FIL_, 0xCC, 0x89, FIL_, 0xE1, 0xBA, 0xB3, - FIL_, 0x02, 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x96, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xB8, 0x94, FIL_, - 0x02, 0xCC, 0x80, FIL_, 0xE1, 0xB8, 0x95, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xB8, 0x97, FIL_, 0x02, - 0xCC, 0x80, FIL_, 0xE1, 0xB9, 0x90, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xB9, 0x92, FIL_, 0x02, 0xCC, - 0x81, FIL_, 0xE1, 0xB9, 0x93, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xB9, 0x91, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA4, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA5, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA6, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xB9, 0xA7, FIL_, 0x01, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0xB8, FIL_, 0x01, 0xCC, 0x81, - FIL_, 0xE1, 0xB9, 0xB9, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xE1, 0xB9, 0xBA, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xE1, 0xB9, 0xBB, FIL_, 0x01, 0xCC, 0x87, - FIL_, 0xE1, 0xBA, 0x9B, FIL_, 0x05, 0xCC, 0x80, - FIL_, 0xE1, 0xBB, 0x9C, FIL_, 0xCC, 0x89, FIL_, - 0xE1, 0xBB, 0x9E, FIL_, 0xCC, 0x83, FIL_, 0xE1, - 0xBB, 0xA0, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBB, - 0x9A, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xA2, - FIL_, 0x05, 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xA1, - FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xA3, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xBB, 0x9B, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBB, 0x9D, FIL_, 0xCC, 0x89, - FIL_, 0xE1, 0xBB, 0x9F, FIL_, 0x05, 0xCC, 0x81, - FIL_, 0xE1, 0xBB, 0xA8, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBB, 0xAA, FIL_, 0xCC, 0x89, FIL_, 0xE1, - 0xBB, 0xAC, FIL_, 0xCC, 0x83, FIL_, 0xE1, 0xBB, - 0xAE, FIL_, 0xCC, 0xA3, FIL_, 0xE1, 0xBB, 0xB0, - FIL_, 0x05, 0xCC, 0x80, FIL_, 0xE1, 0xBB, 0xAB, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBB, 0xA9, FIL_, - 0xCC, 0x83, FIL_, 0xE1, 0xBB, 0xAF, FIL_, 0xCC, - 0xA3, FIL_, 0xE1, 0xBB, 0xB1, FIL_, 0xCC, 0x89, - FIL_, 0xE1, 0xBB, 0xAD, FIL_, 0x01, 0xCC, 0x8C, - FIL_, 0xC7, 0xAE, FIL_, 0x01, 0xCC, 0x84, FIL_, - 0xC7, 0xAC, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, - 0xAD, FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, 0xA0, - FIL_, 0x01, 0xCC, 0x84, FIL_, 0xC7, 0xA1, FIL_, - 0x01, 0xCC, 0x86, FIL_, 0xE1, 0xB8, 0x9C, FIL_, - 0x01, 0xCC, 0x86, FIL_, 0xE1, 0xB8, 0x9D, FIL_, - 0x01, 0xCC, 0x84, FIL_, 0xC8, 0xB0, FIL_, 0x01, - 0xCC, 0x84, FIL_, 0xC8, 0xB1, FIL_, 0x01, 0xCC, - 0x8C, FIL_, 0xC7, 0xAF, FIL_, 0x07, 0xCC, 0x93, - FIL_, 0xE1, 0xBC, 0x88, FIL_, 0xCC, 0x81, FIL_, - 0xCE, 0x86, FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBE, - 0xB8, FIL_, 0xCC, 0x84, FIL_, 0xE1, 0xBE, 0xB9, - FIL_, 0xCC, 0x94, FIL_, 0xE1, 0xBC, 0x89, FIL_, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xBC, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBE, 0xBA, FIL_, 0x04, 0xCC, - 0x94, FIL_, 0xE1, 0xBC, 0x99, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBF, 0x88, FIL_, 0xCC, 0x81, FIL_, - 0xCE, 0x88, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBC, - 0x98, FIL_, 0x05, 0xCD, 0x85, FIL_, 0xE1, 0xBF, - 0x8C, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0x89, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0x8A, FIL_, 0xCC, - 0x93, FIL_, 0xE1, 0xBC, 0xA8, FIL_, 0xCC, 0x94, - FIL_, 0xE1, 0xBC, 0xA9, FIL_, 0x07, 0xCC, 0x80, - FIL_, 0xE1, 0xBF, 0x9A, FIL_, 0xCC, 0x84, FIL_, - 0xE1, 0xBF, 0x99, FIL_, 0xCC, 0x93, FIL_, 0xE1, - 0xBC, 0xB8, FIL_, 0xCC, 0x94, FIL_, 0xE1, 0xBC, - 0xB9, FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBF, 0x98, - FIL_, 0xCC, 0x81, FIL_, 0xCE, 0x8A, FIL_, 0xCC, - 0x88, FIL_, 0xCE, 0xAA, FIL_, 0x04, 0xCC, 0x81, - FIL_, 0xCE, 0x8C, FIL_, 0xCC, 0x94, FIL_, 0xE1, - 0xBD, 0x89, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBD, - 0x88, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0xB8, - FIL_, 0x01, 0xCC, 0x94, FIL_, 0xE1, 0xBF, 0xAC, - FIL_, 0x06, 0xCC, 0x94, FIL_, 0xE1, 0xBD, 0x99, - FIL_, 0xCC, 0x86, FIL_, 0xE1, 0xBF, 0xA8, FIL_, - 0xCC, 0x88, FIL_, 0xCE, 0xAB, FIL_, 0xCC, 0x84, - FIL_, 0xE1, 0xBF, 0xA9, FIL_, 0xCC, 0x81, FIL_, - 0xCE, 0x8E, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, - 0xAA, FIL_, 0x05, 0xCC, 0x93, FIL_, 0xE1, 0xBD, - 0xA8, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xBC, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0xBA, FIL_, - 0xCC, 0x94, FIL_, 0xE1, 0xBD, 0xA9, FIL_, 0xCC, - 0x81, FIL_, 0xCE, 0x8F, FIL_, 0x01, 0xCD, 0x85, - FIL_, 0xE1, 0xBE, 0xB4, FIL_, 0x01, 0xCD, 0x85, - FIL_, 0xE1, 0xBF, 0x84, FIL_, 0x08, 0xCD, 0x85, - FIL_, 0xE1, 0xBE, 0xB3, FIL_, 0xCC, 0x84, FIL_, - 0xE1, 0xBE, 0xB1, FIL_, 0xCC, 0x86, FIL_, 0xE1, - 0xBE, 0xB0, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, - 0xB0, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAC, FIL_, - 0xCC, 0x94, FIL_, 0xE1, 0xBC, 0x81, FIL_, 0xCC, - 0x93, FIL_, 0xE1, 0xBC, 0x80, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBE, 0xB6, FIL_, 0x04, 0xCC, 0x93, - FIL_, 0xE1, 0xBC, 0x90, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBD, 0xB2, FIL_, 0xCC, 0x94, FIL_, 0xE1, - 0xBC, 0x91, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAD, - FIL_, 0x06, 0xCC, 0x94, FIL_, 0xE1, 0xBC, 0xA1, - FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAE, FIL_, 0xCD, - 0x85, FIL_, 0xE1, 0xBF, 0x83, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBF, 0x86, FIL_, 0xCC, 0x93, FIL_, - 0xE1, 0xBC, 0xA0, FIL_, 0xCC, 0x80, FIL_, 0xE1, - 0xBD, 0xB4, FIL_, 0x08, 0xCC, 0x88, FIL_, 0xCF, - 0x8A, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xAF, FIL_, - 0xCC, 0x93, FIL_, 0xE1, 0xBC, 0xB0, FIL_, 0xCC, - 0x94, FIL_, 0xE1, 0xBC, 0xB1, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBD, 0xB6, FIL_, 0xCC, 0x86, FIL_, - 0xE1, 0xBF, 0x90, FIL_, 0xCC, 0x84, FIL_, 0xE1, - 0xBF, 0x91, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, - 0x96, FIL_, 0x04, 0xCC, 0x93, FIL_, 0xE1, 0xBD, - 0x80, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xB8, - FIL_, 0xCC, 0x94, FIL_, 0xE1, 0xBD, 0x81, FIL_, - 0xCC, 0x81, FIL_, 0xCF, 0x8C, FIL_, 0x02, 0xCC, - 0x93, FIL_, 0xE1, 0xBF, 0xA4, FIL_, 0xCC, 0x94, - FIL_, 0xE1, 0xBF, 0xA5, FIL_, 0x08, 0xCC, 0x81, - FIL_, 0xCF, 0x8D, FIL_, 0xCC, 0x94, FIL_, 0xE1, - 0xBD, 0x91, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, - 0xA6, FIL_, 0xCC, 0x88, FIL_, 0xCF, 0x8B, FIL_, - 0xCC, 0x84, FIL_, 0xE1, 0xBF, 0xA1, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBD, 0xBA, FIL_, 0xCC, 0x93, - FIL_, 0xE1, 0xBD, 0x90, FIL_, 0xCC, 0x86, FIL_, - 0xE1, 0xBF, 0xA0, FIL_, 0x06, 0xCC, 0x80, FIL_, - 0xE1, 0xBD, 0xBC, FIL_, 0xCC, 0x94, FIL_, 0xE1, - 0xBD, 0xA1, FIL_, 0xCC, 0x93, FIL_, 0xE1, 0xBD, - 0xA0, FIL_, 0xCC, 0x81, FIL_, 0xCF, 0x8E, FIL_, - 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB3, FIL_, 0xCD, - 0x82, FIL_, 0xE1, 0xBF, 0xB6, FIL_, 0x03, 0xCC, - 0x80, FIL_, 0xE1, 0xBF, 0x92, FIL_, 0xCD, 0x82, - FIL_, 0xE1, 0xBF, 0x97, FIL_, 0xCC, 0x81, FIL_, - 0xCE, 0x90, FIL_, 0x03, 0xCD, 0x82, FIL_, 0xE1, - 0xBF, 0xA7, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, - 0xA2, FIL_, 0xCC, 0x81, FIL_, 0xCE, 0xB0, FIL_, - 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB4, FIL_, - 0x02, 0xCC, 0x88, FIL_, 0xCF, 0x94, FIL_, 0xCC, - 0x81, FIL_, 0xCF, 0x93, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xD0, 0x87, FIL_, 0x02, 0xCC, 0x88, FIL_, - 0xD3, 0x92, FIL_, 0xCC, 0x86, FIL_, 0xD3, 0x90, - FIL_, 0x01, 0xCC, 0x81, FIL_, 0xD0, 0x83, FIL_, - 0x03, 0xCC, 0x88, FIL_, 0xD0, 0x81, FIL_, 0xCC, - 0x80, FIL_, 0xD0, 0x80, FIL_, 0xCC, 0x86, FIL_, - 0xD3, 0x96, FIL_, 0x02, 0xCC, 0x86, FIL_, 0xD3, - 0x81, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x9C, FIL_, - 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9E, FIL_, 0x04, - 0xCC, 0x84, FIL_, 0xD3, 0xA2, FIL_, 0xCC, 0x88, - FIL_, 0xD3, 0xA4, FIL_, 0xCC, 0x86, FIL_, 0xD0, - 0x99, FIL_, 0xCC, 0x80, FIL_, 0xD0, 0x8D, FIL_, - 0x01, 0xCC, 0x81, FIL_, 0xD0, 0x8C, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xA6, FIL_, 0x04, 0xCC, - 0x8B, FIL_, 0xD3, 0xB2, FIL_, 0xCC, 0x88, FIL_, - 0xD3, 0xB0, FIL_, 0xCC, 0x86, FIL_, 0xD0, 0x8E, - FIL_, 0xCC, 0x84, FIL_, 0xD3, 0xAE, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xB4, FIL_, 0x01, 0xCC, - 0x88, FIL_, 0xD3, 0xB8, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xD3, 0xAC, FIL_, 0x02, 0xCC, 0x86, FIL_, - 0xD3, 0x91, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x93, - FIL_, 0x01, 0xCC, 0x81, FIL_, 0xD1, 0x93, FIL_, - 0x03, 0xCC, 0x80, FIL_, 0xD1, 0x90, FIL_, 0xCC, - 0x86, FIL_, 0xD3, 0x97, FIL_, 0xCC, 0x88, FIL_, - 0xD1, 0x91, FIL_, 0x02, 0xCC, 0x86, FIL_, 0xD3, - 0x82, FIL_, 0xCC, 0x88, FIL_, 0xD3, 0x9D, FIL_, - 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9F, FIL_, 0x04, - 0xCC, 0x86, FIL_, 0xD0, 0xB9, FIL_, 0xCC, 0x88, - FIL_, 0xD3, 0xA5, FIL_, 0xCC, 0x84, FIL_, 0xD3, - 0xA3, FIL_, 0xCC, 0x80, FIL_, 0xD1, 0x9D, FIL_, - 0x01, 0xCC, 0x81, FIL_, 0xD1, 0x9C, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xA7, FIL_, 0x04, 0xCC, - 0x8B, FIL_, 0xD3, 0xB3, FIL_, 0xCC, 0x84, FIL_, - 0xD3, 0xAF, FIL_, 0xCC, 0x86, FIL_, 0xD1, 0x9E, - FIL_, 0xCC, 0x88, FIL_, 0xD3, 0xB1, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xB5, FIL_, 0x01, 0xCC, - 0x88, FIL_, 0xD3, 0xB9, FIL_, 0x01, 0xCC, 0x88, - FIL_, 0xD3, 0xAD, FIL_, 0x01, 0xCC, 0x88, FIL_, - 0xD1, 0x97, FIL_, 0x01, 0xCC, 0x8F, FIL_, 0xD1, - 0xB6, FIL_, 0x01, 0xCC, 0x8F, FIL_, 0xD1, 0xB7, - FIL_, 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9A, FIL_, - 0x01, 0xCC, 0x88, FIL_, 0xD3, 0x9B, FIL_, 0x01, - 0xCC, 0x88, FIL_, 0xD3, 0xAA, FIL_, 0x01, 0xCC, - 0x88, FIL_, 0xD3, 0xAB, FIL_, 0x03, 0xD9, 0x94, - FIL_, 0xD8, 0xA3, FIL_, 0xD9, 0x95, FIL_, 0xD8, - 0xA5, FIL_, 0xD9, 0x93, FIL_, 0xD8, 0xA2, FIL_, - 0x01, 0xD9, 0x94, FIL_, 0xD8, 0xA4, FIL_, 0x01, - 0xD9, 0x94, FIL_, 0xD8, 0xA6, FIL_, 0x01, 0xD9, - 0x94, FIL_, 0xDB, 0x82, FIL_, 0x01, 0xD9, 0x94, - FIL_, 0xDB, 0x93, FIL_, 0x01, 0xD9, 0x94, FIL_, - 0xDB, 0x80, FIL_, 0x01, 0xE0, 0xA4, 0xBC, FIL_, - 0xE0, 0xA4, 0xA9, FIL_, 0x01, 0xE0, 0xA4, 0xBC, - FIL_, 0xE0, 0xA4, 0xB1, FIL_, 0x01, 0xE0, 0xA4, - 0xBC, FIL_, 0xE0, 0xA4, 0xB4, FIL_, 0x02, 0xE0, - 0xA6, 0xBE, FIL_, 0xE0, 0xA7, 0x8B, FIL_, 0xE0, - 0xA7, 0x97, FIL_, 0xE0, 0xA7, 0x8C, FIL_, 0x03, - 0xE0, 0xAD, 0x96, FIL_, 0xE0, 0xAD, 0x88, FIL_, - 0xE0, 0xAC, 0xBE, FIL_, 0xE0, 0xAD, 0x8B, FIL_, - 0xE0, 0xAD, 0x97, FIL_, 0xE0, 0xAD, 0x8C, FIL_, - 0x01, 0xE0, 0xAF, 0x97, FIL_, 0xE0, 0xAE, 0x94, - FIL_, 0x02, 0xE0, 0xAF, 0x97, FIL_, 0xE0, 0xAF, - 0x8C, FIL_, 0xE0, 0xAE, 0xBE, FIL_, 0xE0, 0xAF, - 0x8A, FIL_, 0x01, 0xE0, 0xAE, 0xBE, FIL_, 0xE0, - 0xAF, 0x8B, FIL_, 0x01, 0xE0, 0xB1, 0x96, FIL_, - 0xE0, 0xB1, 0x88, FIL_, 0x01, 0xE0, 0xB3, 0x95, - FIL_, 0xE0, 0xB3, 0x80, FIL_, 0x03, 0xE0, 0xB3, - 0x82, FIL_, 0xE0, 0xB3, 0x8A, FIL_, 0xE0, 0xB3, - 0x96, FIL_, 0xE0, 0xB3, 0x88, FIL_, 0xE0, 0xB3, - 0x95, FIL_, 0xE0, 0xB3, 0x87, FIL_, 0x01, 0xE0, - 0xB3, 0x95, FIL_, 0xE0, 0xB3, 0x8B, FIL_, 0x02, - 0xE0, 0xB4, 0xBE, FIL_, 0xE0, 0xB5, 0x8A, FIL_, - 0xE0, 0xB5, 0x97, FIL_, 0xE0, 0xB5, 0x8C, FIL_, - 0x01, 0xE0, 0xB4, 0xBE, FIL_, 0xE0, 0xB5, 0x8B, - FIL_, 0x03, 0xE0, 0xB7, 0x9F, FIL_, 0xE0, 0xB7, - 0x9E, FIL_, 0xE0, 0xB7, 0x8A, FIL_, 0xE0, 0xB7, - 0x9A, FIL_, 0xE0, 0xB7, 0x8F, FIL_, 0xE0, 0xB7, - 0x9C, FIL_, 0x01, 0xE0, 0xB7, 0x8A, FIL_, 0xE0, - 0xB7, 0x9D, FIL_, 0x01, 0xE1, 0x80, 0xAE, FIL_, - 0xE1, 0x80, 0xA6, FIL_, 0x01, 0xE1, 0xAC, 0xB5, - FIL_, 0xE1, 0xAC, 0x86, FIL_, 0x01, 0xE1, 0xAC, - 0xB5, FIL_, 0xE1, 0xAC, 0x88, FIL_, 0x01, 0xE1, - 0xAC, 0xB5, FIL_, 0xE1, 0xAC, 0x8A, FIL_, 0x01, - 0xE1, 0xAC, 0xB5, FIL_, 0xE1, 0xAC, 0x8C, FIL_, - 0x01, 0xE1, 0xAC, 0xB5, FIL_, 0xE1, 0xAC, 0x8E, - FIL_, 0x01, 0xE1, 0xAC, 0xB5, FIL_, 0xE1, 0xAC, - 0x92, FIL_, 0x01, 0xE1, 0xAC, 0xB5, FIL_, 0xE1, - 0xAC, 0xBB, FIL_, 0x01, 0xE1, 0xAC, 0xB5, FIL_, - 0xE1, 0xAC, 0xBD, FIL_, 0x01, 0xE1, 0xAC, 0xB5, - FIL_, 0xE1, 0xAD, 0x80, FIL_, 0x01, 0xE1, 0xAC, - 0xB5, FIL_, 0xE1, 0xAD, 0x81, FIL_, 0x01, 0xE1, - 0xAC, 0xB5, FIL_, 0xE1, 0xAD, 0x83, FIL_, 0x01, - 0xCC, 0x84, FIL_, 0xE1, 0xB8, 0xB8, FIL_, 0x01, - 0xCC, 0x84, FIL_, 0xE1, 0xB8, 0xB9, FIL_, 0x01, - 0xCC, 0x84, FIL_, 0xE1, 0xB9, 0x9C, FIL_, 0x01, - 0xCC, 0x84, FIL_, 0xE1, 0xB9, 0x9D, FIL_, 0x01, - 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xA8, FIL_, 0x01, - 0xCC, 0x87, FIL_, 0xE1, 0xB9, 0xA9, FIL_, 0x02, - 0xCC, 0x86, FIL_, 0xE1, 0xBA, 0xB6, FIL_, 0xCC, - 0x82, FIL_, 0xE1, 0xBA, 0xAC, FIL_, 0x02, 0xCC, - 0x82, FIL_, 0xE1, 0xBA, 0xAD, FIL_, 0xCC, 0x86, - FIL_, 0xE1, 0xBA, 0xB7, FIL_, 0x01, 0xCC, 0x82, - FIL_, 0xE1, 0xBB, 0x86, FIL_, 0x01, 0xCC, 0x82, - FIL_, 0xE1, 0xBB, 0x87, FIL_, 0x01, 0xCC, 0x82, - FIL_, 0xE1, 0xBB, 0x98, FIL_, 0x01, 0xCC, 0x82, - FIL_, 0xE1, 0xBB, 0x99, FIL_, 0x04, 0xCD, 0x85, - FIL_, 0xE1, 0xBE, 0x80, FIL_, 0xCD, 0x82, FIL_, - 0xE1, 0xBC, 0x86, FIL_, 0xCC, 0x80, FIL_, 0xE1, - 0xBC, 0x82, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, - 0x84, FIL_, 0x04, 0xCD, 0x82, FIL_, 0xE1, 0xBC, - 0x87, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x85, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x83, FIL_, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x81, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x82, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x83, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x84, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x85, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x86, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x87, FIL_, 0x04, - 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x8C, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBC, 0x8A, FIL_, 0xCD, 0x85, - FIL_, 0xE1, 0xBE, 0x88, FIL_, 0xCD, 0x82, FIL_, - 0xE1, 0xBC, 0x8E, FIL_, 0x04, 0xCC, 0x80, FIL_, - 0xE1, 0xBC, 0x8B, FIL_, 0xCD, 0x82, FIL_, 0xE1, - 0xBC, 0x8F, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, - 0x8D, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x89, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8A, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8B, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8C, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8D, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8E, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x8F, - FIL_, 0x02, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x92, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x94, FIL_, - 0x02, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x93, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0x95, FIL_, 0x02, - 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0x9A, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xBC, 0x9C, FIL_, 0x02, 0xCC, - 0x80, FIL_, 0xE1, 0xBC, 0x9B, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xBC, 0x9D, FIL_, 0x04, 0xCC, 0x80, - FIL_, 0xE1, 0xBC, 0xA2, FIL_, 0xCC, 0x81, FIL_, - 0xE1, 0xBC, 0xA4, FIL_, 0xCD, 0x82, FIL_, 0xE1, - 0xBC, 0xA6, FIL_, 0xCD, 0x85, FIL_, 0xE1, 0xBE, - 0x90, FIL_, 0x04, 0xCD, 0x85, FIL_, 0xE1, 0xBE, - 0x91, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xA5, - FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xA7, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xA3, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x92, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x93, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x94, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x95, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x96, FIL_, 0x01, - 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x97, FIL_, 0x04, - 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xAC, FIL_, 0xCC, - 0x80, FIL_, 0xE1, 0xBC, 0xAA, FIL_, 0xCD, 0x85, - FIL_, 0xE1, 0xBE, 0x98, FIL_, 0xCD, 0x82, FIL_, - 0xE1, 0xBC, 0xAE, FIL_, 0x04, 0xCD, 0x82, FIL_, - 0xE1, 0xBC, 0xAF, FIL_, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0x99, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, - 0xAD, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xAB, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9A, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9B, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9C, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9D, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9E, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0x9F, - FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xB4, - FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xB2, FIL_, - 0xCD, 0x82, FIL_, 0xE1, 0xBC, 0xB6, FIL_, 0x03, - 0xCC, 0x80, FIL_, 0xE1, 0xBC, 0xB3, FIL_, 0xCD, - 0x82, FIL_, 0xE1, 0xBC, 0xB7, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xBC, 0xB5, FIL_, 0x03, 0xCC, 0x81, - FIL_, 0xE1, 0xBC, 0xBC, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBC, 0xBA, FIL_, 0xCD, 0x82, FIL_, 0xE1, - 0xBC, 0xBE, FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1, - 0xBC, 0xBB, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBC, - 0xBF, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBC, 0xBD, - FIL_, 0x02, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x82, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x84, FIL_, - 0x02, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x85, FIL_, - 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x83, FIL_, 0x02, - 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x8A, FIL_, 0xCC, - 0x81, FIL_, 0xE1, 0xBD, 0x8C, FIL_, 0x02, 0xCC, - 0x80, FIL_, 0xE1, 0xBD, 0x8B, FIL_, 0xCC, 0x81, - FIL_, 0xE1, 0xBD, 0x8D, FIL_, 0x03, 0xCD, 0x82, - FIL_, 0xE1, 0xBD, 0x96, FIL_, 0xCC, 0x80, FIL_, - 0xE1, 0xBD, 0x92, FIL_, 0xCC, 0x81, FIL_, 0xE1, - 0xBD, 0x94, FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1, - 0xBD, 0x93, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD, - 0x97, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x95, - FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0x9B, - FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0x9F, FIL_, - 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0x9D, FIL_, 0x04, - 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0xA6, FIL_, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xA0, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBD, 0xA2, FIL_, 0xCC, 0x81, FIL_, - 0xE1, 0xBD, 0xA4, FIL_, 0x04, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0xA1, FIL_, 0xCD, 0x82, FIL_, 0xE1, - 0xBD, 0xA7, FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, - 0xA5, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xA3, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA2, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA3, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA4, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA5, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA6, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBE, 0xA7, - FIL_, 0x04, 0xCC, 0x80, FIL_, 0xE1, 0xBD, 0xAA, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBD, 0xAC, FIL_, - 0xCD, 0x82, FIL_, 0xE1, 0xBD, 0xAE, FIL_, 0xCD, - 0x85, FIL_, 0xE1, 0xBE, 0xA8, FIL_, 0x04, 0xCD, - 0x82, FIL_, 0xE1, 0xBD, 0xAF, FIL_, 0xCC, 0x80, - FIL_, 0xE1, 0xBD, 0xAB, FIL_, 0xCD, 0x85, FIL_, - 0xE1, 0xBE, 0xA9, FIL_, 0xCC, 0x81, FIL_, 0xE1, - 0xBD, 0xAD, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xAA, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xAB, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xAC, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xAD, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xAE, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xAF, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xB2, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBF, 0x82, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBF, 0xB2, FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, - 0xBE, 0xB7, FIL_, 0x03, 0xCC, 0x81, FIL_, 0xE1, - 0xBF, 0x8E, FIL_, 0xCC, 0x80, FIL_, 0xE1, 0xBF, - 0x8D, FIL_, 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0x8F, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0x87, - FIL_, 0x01, 0xCD, 0x85, FIL_, 0xE1, 0xBF, 0xB7, - FIL_, 0x03, 0xCC, 0x80, FIL_, 0xE1, 0xBF, 0x9D, - FIL_, 0xCC, 0x81, FIL_, 0xE1, 0xBF, 0x9E, FIL_, - 0xCD, 0x82, FIL_, 0xE1, 0xBF, 0x9F, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x86, 0x9A, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x86, 0x9B, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x86, 0xAE, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x87, 0x8D, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x87, 0x8F, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x87, 0x8E, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x88, 0x84, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x88, 0x89, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x88, 0x8C, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x88, 0xA4, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x88, 0xA6, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0x81, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0x84, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0x87, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0x89, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xAD, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xA2, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB0, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB1, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB4, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB5, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB8, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x89, 0xB9, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x80, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x81, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xA0, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xA1, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x84, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x85, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x88, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0x89, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xA2, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xA3, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0xAC, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0xAD, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0xAE, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8A, 0xAF, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xAA, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xAB, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xAC, FIL_, 0x01, - 0xCC, 0xB8, FIL_, 0xE2, 0x8B, 0xAD, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0x94, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x8C, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, - 0x8E, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x81, 0x90, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x81, 0x92, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x81, 0x94, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x81, 0x96, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x81, 0x98, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x9A, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0x9C, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, - 0x9E, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x81, 0xA0, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x81, 0xA2, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x81, 0xA5, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x81, 0xA7, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x81, 0xA9, FIL_, 0x02, - 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xB1, FIL_, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xB0, FIL_, - 0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, 0xB3, - FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, 0xB4, - FIL_, 0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x81, - 0xB6, FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x81, - 0xB7, FIL_, 0x02, 0xE3, 0x82, 0x9A, FIL_, 0xE3, - 0x81, 0xBA, FIL_, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x81, 0xB9, FIL_, 0x02, 0xE3, 0x82, 0x9A, FIL_, - 0xE3, 0x81, 0xBD, FIL_, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x81, 0xBC, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x82, 0x9E, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x83, 0xB4, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x82, 0xAC, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xAE, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xB0, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, - 0xB2, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x82, 0xB4, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x82, 0xB6, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x82, 0xB8, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x82, 0xBA, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x82, 0xBC, FIL_, 0x01, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x82, 0xBE, FIL_, - 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x80, - FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, - 0x82, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x83, 0x85, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x83, 0x87, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x83, 0x89, FIL_, 0x02, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x83, 0x90, FIL_, 0xE3, 0x82, - 0x9A, FIL_, 0xE3, 0x83, 0x91, FIL_, 0x02, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x83, 0x93, FIL_, 0xE3, - 0x82, 0x9A, FIL_, 0xE3, 0x83, 0x94, FIL_, 0x02, - 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x83, 0x97, FIL_, - 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x96, FIL_, - 0x02, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x83, 0x9A, - FIL_, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, 0x99, - FIL_, 0x02, 0xE3, 0x82, 0x99, FIL_, 0xE3, 0x83, - 0x9C, FIL_, 0xE3, 0x82, 0x9A, FIL_, 0xE3, 0x83, - 0x9D, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, 0xE3, - 0x83, 0xB7, FIL_, 0x01, 0xE3, 0x82, 0x99, FIL_, - 0xE3, 0x83, 0xB8, FIL_, 0x01, 0xE3, 0x82, 0x99, - FIL_, 0xE3, 0x83, 0xB9, FIL_, 0x01, 0xE3, 0x82, - 0x99, FIL_, 0xE3, 0x83, 0xBA, FIL_, 0x01, 0xE3, - 0x82, 0x99, FIL_, 0xE3, 0x83, 0xBE, FIL_, - }, -}; - -static const uchar_t u8_decomp_b2_tbl[2][2][256] = { - { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 1, 2, 3, 4, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, 5, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, 6, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, 7, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - - }, - { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 1, 2, 3, 4, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, 5, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, 6, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, 7, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - - }, - -}; - -static const u8_displacement_t u8_decomp_b3_tbl[2][8][256] = { - { - { /* Third byte table 0. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0, 0 }, - { 1, 35 }, { 2, 247 }, { 3, 474 }, - { 4, 693 }, { 5, 709 }, { 6, 951 }, - { N_, 0 }, { 7, 1139 }, { 8, 1152 }, - { N_, 0 }, { 9, 1177 }, { 10, 1199 }, - { 11, 1295 }, { 12, 1360 }, { 13, 1405 }, - { N_, 0 }, { 14, 1450 }, { N_, 0 }, - { N_, 0 }, { 15, 1620 }, { N_, 0 }, - { 16, 1624 }, { 17, 1649 }, { N_, 0 }, - { 18, 1665 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 1. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 19, 1680 }, - { 20, 1701 }, { N_, 0 }, { 21, 1757 }, - { 22, 1792 }, { 23, 1806 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 24, 1834 }, - { 25, 1869 }, { 26, 1876 }, { N_, 0 }, - { 27, 1897 }, { N_, 0 }, { 28, 1904 }, - { N_, 0 }, { 29, 1942 }, { N_, 0 }, - { 30, 1963 }, { 31, 1994 }, { N_, 0 }, - { 32, 2000 }, { 33, 2006 }, { 34, 2018 }, - { 35, 2021 }, { 36, 2109 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 2. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 37, 2158 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 0x8000, 2165 }, { 0x8001, 2445 }, - { 0x8002, 2741 }, { 0x8003, 3029 }, { 0x8004, 3337 }, - { 0x8005, 3725 }, { 0x8006, 4053 }, { 0x8007, 4536 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 3. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 38, 4895 }, - { 39, 4964 }, { 40, 4999 }, { N_, 0 }, - { 41, 5018 }, { 42, 5098 }, { 43, 5230 }, - { 44, 5248 }, { 45, 5266 }, { 46, 5326 }, - { 47, 5410 }, { 48, 5470 }, { 49, 5518 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 50, 5526 }, { 51, 5596 }, - { 52, 5767 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 53, 5810 }, { 54, 5822 }, { N_, 0 }, - { 55, 5830 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 56, 5836 }, { 57, 5839 }, { 58, 5842 }, - { 59, 6034 }, { 60, 6226 }, { 61, 6418 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 4. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 62, 6484 }, - { 63, 6497 }, { 64, 6672 }, { 65, 6770 }, - { 66, 6923 }, { 67, 6968 }, { 68, 7160 }, - { N_, 0 }, { 0x8008, 7247 }, { 69, 7597 }, - { 70, 7773 }, { 71, 7950 }, { 0x8009, 8142 }, - { 0x800A, 8919 }, { 72, 9351 }, { 73, 9522 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 5. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0x800B, 9743 }, - { 0x800C, 9999 }, { 0x800D, 10255 }, { 0x800E, 10511 }, - { 74, 10767 }, { 75, 10967 }, { N_, 0 }, - { N_, 0 }, { 76, 11139 }, { 77, 11303 }, - { 78, 11468 }, { 79, 11576 }, { 0x800F, 11740 }, - { 0x8010, 12006 }, { 0x8011, 12280 }, { 0x8012, 12546 }, - { 80, 12812 }, { 0x8013, 13060 }, { 0x8014, 13348 }, - { 81, 13720 }, { 82, 13898 }, { 83, 13933 }, - { 84, 14045 }, { 85, 14197 }, { 86, 14347 }, - { 87, 14410 }, { 88, 14540 }, { 89, 14729 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 6. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 90, 14829 }, { 91, 14912 }, - { 92, 14969 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 93, 14982 }, { 94, 15046 }, { 95, 15109 }, - { 96, 15163 }, { 97, 15225 }, { 98, 15282 }, - { 99, 15341 }, { 100, 15405 }, { 101, 15469 }, - { 102, 15533 }, { 103, 15597 }, { 104, 15681 }, - { 105, 15812 }, { 106, 15942 }, { 107, 16072 }, - { 108, 16202 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 7. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 0x8015, 16273 }, { 0x8016, 16536 }, - { 0x8017, 16799 }, { 0x8018, 17064 }, { 0x8019, 17329 }, - { 0x801A, 17601 }, { 0x801B, 17878 }, { 0x801C, 18147 }, - { 109, 18419 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - }, - { - { /* Third byte table 0. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0, 0 }, - { 1, 35 }, { 2, 247 }, { 3, 474 }, - { 4, 693 }, { 5, 709 }, { 6, 951 }, - { N_, 0 }, { 7, 1139 }, { 8, 1152 }, - { N_, 0 }, { 9, 1177 }, { 10, 1199 }, - { 11, 1295 }, { 12, 1362 }, { 13, 1407 }, - { N_, 0 }, { 14, 1452 }, { N_, 0 }, - { N_, 0 }, { 15, 1622 }, { N_, 0 }, - { 16, 1626 }, { 17, 1651 }, { N_, 0 }, - { 18, 1667 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 1. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 19, 1682 }, - { 20, 1703 }, { N_, 0 }, { 21, 1759 }, - { 22, 1794 }, { 23, 1808 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 24, 1836 }, - { 25, 1871 }, { 26, 1878 }, { N_, 0 }, - { 27, 1899 }, { N_, 0 }, { 28, 1906 }, - { N_, 0 }, { 29, 1944 }, { N_, 0 }, - { 30, 1965 }, { 31, 1996 }, { N_, 0 }, - { 32, 2002 }, { 33, 2008 }, { 34, 2020 }, - { 35, 2023 }, { 36, 2111 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 2. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 37, 2160 }, - { N_, 0 }, { N_, 0 }, { 38, 2167 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 39, 2170 }, { 40, 2226 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 41, 2247 }, { 42, 2268 }, { 43, 2340 }, - { N_, 0 }, { 0x8000, 2414 }, { 0x8001, 2694 }, - { 0x8002, 2990 }, { 0x8003, 3278 }, { 0x8004, 3586 }, - { 0x8005, 3974 }, { 0x8006, 4302 }, { 0x8007, 4785 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 3. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 44, 5144 }, - { 45, 5213 }, { 46, 5248 }, { N_, 0 }, - { 47, 5273 }, { 48, 5358 }, { 49, 5490 }, - { 50, 5508 }, { 51, 5526 }, { 52, 5586 }, - { 53, 5670 }, { 54, 5730 }, { 55, 5778 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 56, 5786 }, { 57, 5856 }, - { 58, 6027 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 59, 6070 }, { 60, 6082 }, { N_, 0 }, - { 61, 6090 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 62, 6096 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 63, 6099 }, { 64, 6102 }, { 65, 6105 }, - { 66, 6297 }, { 67, 6489 }, { 68, 6681 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 4. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 69, 6747 }, - { 70, 6760 }, { 71, 6935 }, { 72, 7033 }, - { 73, 7186 }, { 74, 7231 }, { 75, 7423 }, - { N_, 0 }, { 0x8008, 7510 }, { 76, 7891 }, - { 77, 8103 }, { 78, 8280 }, { 0x8009, 8482 }, - { 0x800A, 9259 }, { 79, 9701 }, { 80, 9872 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 5. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0x800B, 10106 }, - { 0x800C, 10362 }, { 0x800D, 10618 }, { 0x800E, 10874 }, - { 81, 11130 }, { 82, 11330 }, { 0x800F, 11566 }, - { 83, 11822 }, { 84, 11932 }, { 85, 12096 }, - { 86, 12261 }, { 87, 12369 }, { 0x8010, 12533 }, - { 0x8011, 12799 }, { 0x8012, 13073 }, { 0x8013, 13339 }, - { 88, 13605 }, { 0x8014, 13853 }, { 0x8015, 14141 }, - { 89, 14513 }, { 90, 14691 }, { 91, 14746 }, - { 92, 14860 }, { 93, 15012 }, { 94, 15162 }, - { 95, 15225 }, { 96, 15355 }, { 97, 15544 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 6. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 98, 15644 }, { 99, 15727 }, - { 100, 15784 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 101, 15797 }, { 102, 15861 }, { 103, 15924 }, - { 104, 15978 }, { 105, 16041 }, { 106, 16098 }, - { 107, 16157 }, { 108, 16221 }, { 109, 16285 }, - { 110, 16349 }, { 111, 16413 }, { 112, 16501 }, - { 113, 16632 }, { 114, 16762 }, { 115, 16892 }, - { 116, 17022 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - { /* Third byte table 7. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 0x8016, 17097 }, { 0x8017, 17360 }, - { 0x8018, 17623 }, { 0x8019, 17888 }, { 0x801A, 18153 }, - { 0x801B, 18425 }, { 0x801C, 18702 }, { 0x801D, 18971 }, - { 117, 19243 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, - }, - }, -}; - -static const uchar_t u8_decomp_b4_tbl[2][118][257] = { - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 4, 4, 5, 5, 5, 5, 5, - 8, 8, 8, 9, 10, 13, 15, 15, - 15, 18, 19, 20, 20, 25, 30, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 24, - 28, 32, 36, 40, 44, 48, 52, 56, - 60, 60, 64, 68, 72, 76, 80, 84, - 84, 84, 88, 92, 96, 100, 104, 104, - 104, 108, 112, 116, 120, 124, 128, 128, - 132, 136, 140, 144, 148, 152, 156, 160, - 164, 164, 168, 172, 176, 180, 184, 188, - 188, 188, 192, 196, 200, 204, 208, 208, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 64, 64, 68, 72, 76, 80, 84, - 88, 92, 96, 100, 104, 108, 112, 116, - 120, 124, 128, 132, 136, 140, 144, 144, - 144, 148, 152, 156, 160, 164, 168, 172, - 176, 180, 180, 182, 184, 188, 192, 196, - 200, 200, 204, 208, 212, 216, 220, 224, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 3, 7, 11, 15, 19, - 23, 27, 30, 30, 30, 34, 38, 42, - 46, 50, 54, 54, 54, 58, 62, 66, - 70, 74, 78, 82, 86, 90, 94, 98, - 102, 106, 110, 114, 118, 122, 126, 126, - 126, 130, 134, 138, 142, 146, 150, 154, - 158, 162, 166, 170, 174, 178, 182, 186, - 190, 194, 198, 202, 206, 210, 214, 218, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 12, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 8, 12, - 14, 16, 18, 20, 22, 24, 28, 32, - 36, 40, 44, 48, 52, 56, 62, 68, - 74, 80, 86, 92, 98, 104, 104, 110, - 116, 122, 128, 133, 138, 138, 138, 142, - 146, 150, 154, 158, 162, 168, 174, 179, - 184, 188, 190, 192, 194, 198, 202, 202, - 202, 206, 210, 216, 222, 227, 232, 237, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 112, 112, 116, - 120, 120, 120, 120, 120, 120, 120, 124, - 128, 132, 136, 142, 148, 154, 160, 164, - 168, 174, 180, 184, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 3, 4, 5, 7, 9, 11, - 12, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 18, - 18, 20, 21, 22, 23, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 6, 9, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 17, 17, 17, - 17, 17, 17, 20, 20, 20, 20, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 14, 19, - 22, 27, 32, 37, 37, 42, 42, 47, - 52, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 64, 69, 74, 79, 84, - 89, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 10, 15, 20, 25, - 25, 27, 29, 31, 41, 51, 53, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 57, 59, 61, 61, 63, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 10, 15, 15, 15, 15, - 20, 20, 20, 20, 20, 25, 30, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 10, 15, 15, 15, 15, - 20, 20, 20, 20, 20, 25, 30, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 40, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 15, 20, 25, 30, 30, 30, 35, - 40, 40, 40, 45, 50, 55, 60, 65, - 70, 70, 70, 75, 80, 85, 90, 95, - 100, 100, 100, 105, 110, 115, 120, 125, - 130, 135, 140, 145, 150, 155, 160, 160, - 160, 165, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 10, 15, 20, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 8, - 12, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 7, 7, 7, 7, 7, - 7, 7, 14, 14, 14, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 14, 21, 28, 35, 42, 49, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 21, 28, 28, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 7, 7, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 14, 21, 21, 21, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 7, 14, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 28, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 14, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 7, 7, 7, 7, 7, - 14, 21, 21, 28, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 14, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 7, 14, 24, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 14, 14, - 14, 14, 14, 21, 21, 21, 21, 21, - 28, 28, 28, 28, 28, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 49, 49, 56, 63, - 72, 79, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, - }, - { /* Fourth byte table 36. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 21, 21, - 21, 21, 21, 28, 28, 28, 28, 28, - 35, 35, 35, 35, 35, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, - }, - { /* Fourth byte table 37. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, - }, - { /* Fourth byte table 38. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 21, 21, 21, 21, - 21, 21, 24, 24, 24, 24, 24, 24, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 28, 30, 33, - 33, 33, 33, 33, 33, 33, 33, 33, - 34, 34, 34, 34, 40, 49, 49, 55, - 64, 64, 64, 64, 64, 66, 66, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, - }, - { /* Fourth byte table 39. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 2, 4, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 18, 18, 18, 18, 18, 18, 18, 18, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 20, 21, 21, 21, 22, 23, 24, - 25, 26, 27, 28, 31, 32, 33, 34, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 40. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 14, 15, 16, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, - }, - { /* Fourth byte table 41. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 7, 10, 10, 13, 16, - 18, 18, 21, 22, 23, 24, 25, 26, - 28, 29, 30, 31, 32, 32, 33, 35, - 35, 35, 36, 37, 38, 39, 40, 40, - 40, 42, 45, 47, 47, 48, 48, 51, - 51, 52, 52, 54, 58, 59, 60, 60, - 61, 62, 63, 63, 64, 65, 67, 69, - 71, 73, 74, 74, 74, 74, 76, 78, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, - }, - { /* Fourth byte table 42. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 3, 3, 3, 4, 5, - 6, 7, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 13, 18, 23, 28, - 33, 38, 43, 48, 53, 58, 63, 68, - 72, 73, 75, 78, 80, 81, 83, 86, - 90, 92, 93, 95, 98, 99, 100, 101, - 102, 103, 105, 108, 110, 111, 113, 116, - 120, 122, 123, 125, 128, 129, 130, 131, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, - }, - { /* Fourth byte table 43. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, - }, - { /* Fourth byte table 44. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6, 12, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, - }, - { /* Fourth byte table 45. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 6, 6, - 6, 6, 12, 12, 12, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 24, 24, 30, - 30, 30, 30, 30, 30, 36, 45, 45, - 51, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, - }, - { /* Fourth byte table 46. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 6, 6, 6, 12, 12, 12, - 18, 18, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 28, 28, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 40, 44, - 48, 54, 60, 60, 60, 66, 72, 72, - 72, 78, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, - }, - { /* Fourth byte table 47. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 12, 12, 18, 24, 24, - 24, 30, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 42, 48, 54, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, - }, - { /* Fourth byte table 48. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 24, 24, 24, - 24, 24, 24, 30, 36, 42, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 49. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, - }, - { /* Fourth byte table 50. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 11, 13, 15, 17, 19, 21, - 23, 25, 27, 29, 31, 34, 37, 40, - 43, 46, 49, 52, 55, 58, 62, 66, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, - }, - { /* Fourth byte table 51. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 53, 56, 59, 62, 65, 68, - 71, 74, 77, 80, 83, 86, 89, 92, - 95, 98, 101, 104, 107, 110, 113, 116, - 119, 122, 125, 128, 131, 134, 137, 140, - 143, 146, 149, 152, 155, 158, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, - }, - { /* Fourth byte table 52. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, - }, - { /* Fourth byte table 53. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, - }, - { /* Fourth byte table 54. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 5, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, - }, - { /* Fourth byte table 55. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, - }, - { /* Fourth byte table 56. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 57. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 58. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 59. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 60. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 61. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, - }, - { /* Fourth byte table 62. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 4, - 4, 7, 10, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, - }, - { /* Fourth byte table 63. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 7, 14, - 14, 21, 21, 28, 28, 35, 35, 42, - 42, 49, 49, 56, 56, 63, 63, 70, - 70, 77, 77, 84, 84, 84, 91, 91, - 98, 98, 105, 105, 105, 105, 105, 105, - 105, 112, 119, 119, 126, 133, 133, 140, - 147, 147, 154, 161, 161, 168, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, - }, - { /* Fourth byte table 64. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 7, 7, - 7, 7, 7, 7, 11, 15, 15, 22, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 35, 35, 42, - 42, 49, 49, 56, 56, 63, 63, 70, - 70, 77, 77, 84, 84, 91, 91, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, - }, - { /* Fourth byte table 65. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 14, 14, 14, 21, 21, - 28, 28, 35, 35, 35, 35, 35, 35, - 35, 42, 49, 49, 56, 63, 63, 70, - 77, 77, 84, 91, 91, 98, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 112, 112, 112, - 119, 126, 133, 140, 140, 140, 140, 147, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, - }, - { /* Fourth byte table 66. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 6, 9, 12, 15, 18, - 21, 24, 27, 30, 33, 36, 39, 42, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, - }, - { /* Fourth byte table 67. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 68. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 45, 45, 45, 48, 51, 54, 57, 60, - 63, 66, 69, 72, 75, 78, 81, 84, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, - }, - { /* Fourth byte table 69. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 15, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 22, 24, 26, 28, 30, 32, - 34, 36, 38, 40, 42, 44, 46, 48, - 50, 53, 56, 59, 62, 65, 68, 71, - 74, 77, 80, 83, 86, 89, 92, 98, - 104, 110, 116, 122, 128, 134, 140, 146, - 152, 158, 164, 170, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, - }, - { /* Fourth byte table 70. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 149, 151, 153, 155, 157, 159, - 161, 163, 165, 167, 169, 171, 173, 175, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, - }, - { /* Fourth byte table 71. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 41, 46, 51, 51, 51, 51, - 51, 54, 57, 60, 63, 66, 69, 72, - 75, 78, 81, 84, 87, 90, 93, 96, - 99, 102, 105, 108, 111, 114, 117, 120, - 123, 126, 129, 132, 135, 138, 141, 144, - 147, 150, 153, 156, 159, 162, 165, 168, - 171, 174, 177, 180, 183, 186, 189, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 72. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 7, 9, 11, 13, 15, - 17, 20, 24, 26, 28, 31, 34, 36, - 38, 40, 43, 46, 49, 52, 55, 57, - 59, 61, 63, 65, 68, 70, 72, 74, - 77, 80, 82, 85, 88, 91, 93, 96, - 101, 107, 109, 112, 115, 118, 121, 128, - 136, 138, 140, 143, 145, 147, 149, 152, - 154, 156, 158, 160, 162, 165, 167, 169, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, - }, - { /* Fourth byte table 73. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 10, 12, 14, 16, 22, - 25, 27, 29, 31, 33, 35, 37, 39, - 41, 43, 45, 48, 50, 52, 55, 58, - 60, 64, 67, 69, 71, 73, 75, 75, - 75, 79, 83, 87, 91, 95, 99, 103, - 107, 111, 116, 121, 126, 131, 136, 141, - 146, 151, 156, 161, 166, 171, 176, 181, - 186, 191, 196, 201, 206, 211, 216, 221, - 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, - 221, - }, - { /* Fourth byte table 74. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 56, - 56, 60, 60, 64, 64, 64, 68, 72, - 76, 80, 84, 88, 92, 96, 100, 104, - 104, 108, 108, 112, 112, 112, 116, 120, - 120, 120, 120, 124, 128, 132, 136, 136, - 136, 140, 144, 148, 152, 156, 160, 164, - 168, 172, 176, 180, 184, 188, 192, 196, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, - }, - { /* Fourth byte table 75. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, - 172, - }, - { /* Fourth byte table 76. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 9, 12, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 20, 24, 28, 32, - 36, 36, 36, 36, 36, 36, 41, 41, - 46, 48, 50, 52, 54, 56, 58, 60, - 62, 64, 65, 70, 75, 82, 89, 94, - 99, 104, 109, 114, 119, 124, 129, 134, - 134, 139, 144, 149, 154, 159, 159, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, - }, - { /* Fourth byte table 77. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 10, 15, 20, 20, 25, - 30, 35, 40, 45, 50, 55, 60, 65, - 69, 71, 73, 75, 77, 79, 81, 83, - 85, 87, 89, 91, 93, 95, 97, 99, - 101, 103, 105, 107, 109, 111, 113, 115, - 117, 119, 121, 123, 125, 127, 129, 131, - 133, 135, 137, 139, 141, 143, 145, 147, - 149, 151, 153, 155, 157, 159, 161, 163, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, - }, - { /* Fourth byte table 78. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - 64, 66, 68, 70, 72, 76, 80, 82, - 84, 86, 88, 90, 92, 94, 96, 98, - 100, 104, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, - }, - { /* Fourth byte table 79. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 4, 6, 8, - 10, 12, 14, 16, 18, 20, 24, 26, - 28, 30, 32, 34, 36, 38, 40, 42, - 44, 46, 48, 54, 60, 66, 72, 78, - 84, 90, 96, 102, 108, 114, 120, 126, - 132, 138, 144, 150, 156, 158, 160, 162, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, - }, - { /* Fourth byte table 80. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, - }, - { /* Fourth byte table 81. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 36, 42, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 54, 60, 68, 76, 84, 92, 100, - 108, 116, 122, 155, 170, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, - }, - { /* Fourth byte table 82. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 5, 8, 9, 10, 11, 12, - 13, 14, 17, 20, 23, 26, 29, 32, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 83. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 15, 15, - 15, 15, 18, 21, 24, 27, 28, 29, - 30, 31, 34, 35, 35, 36, 37, 38, - 39, 42, 43, 44, 45, 46, 49, 52, - 53, 54, 55, 56, 57, 58, 59, 60, - 60, 61, 62, 63, 64, 64, 64, 64, - 64, 67, 71, 74, 74, 77, 77, 80, - 84, 87, 91, 94, 98, 101, 105, 108, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, - }, - { /* Fourth byte table 84. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 6, 10, 14, 18, 22, 26, - 30, 34, 38, 42, 46, 50, 52, 54, - 56, 58, 60, 62, 64, 66, 68, 70, - 72, 74, 76, 78, 80, 82, 84, 86, - 88, 90, 92, 94, 96, 98, 100, 102, - 104, 106, 108, 110, 112, 114, 116, 118, - 120, 122, 124, 126, 128, 130, 132, 134, - 136, 138, 140, 142, 144, 146, 148, 150, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, - }, - { /* Fourth byte table 85. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - 64, 66, 68, 70, 72, 74, 76, 78, - 80, 82, 84, 86, 88, 90, 92, 94, - 96, 98, 100, 102, 104, 106, 112, 118, - 124, 130, 136, 142, 146, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, - }, - { /* Fourth byte table 86. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 87. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 34, 37, 40, 43, 46, 49, 52, 55, - 58, 61, 64, 67, 70, 73, 76, 79, - 82, 85, 88, 91, 94, 97, 100, 103, - 106, 109, 112, 115, 118, 121, 124, 127, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, - }, - { /* Fourth byte table 88. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, - }, - { /* Fourth byte table 89. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 6, 9, 12, 15, - 18, 18, 18, 21, 24, 27, 30, 33, - 36, 36, 36, 39, 42, 45, 48, 51, - 54, 54, 54, 57, 60, 63, 63, 63, - 63, 65, 67, 69, 72, 74, 76, 79, - 79, 82, 85, 88, 91, 94, 97, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, - }, - { /* Fourth byte table 90. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, - 18, 31, 44, 57, 70, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, - }, - { /* Fourth byte table 91. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 18, 31, 44, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, - }, - { /* Fourth byte table 92. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, - }, - { /* Fourth byte table 93. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 94. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 95. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 29, 30, - 31, 31, 31, 32, 32, 32, 33, 34, - 34, 34, 35, 36, 37, 38, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 50, 51, 51, 52, 53, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, - }, - { /* Fourth byte table 96. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 2, 3, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 97. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 6, - 7, 8, 9, 10, 10, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 18, 19, - 20, 21, 22, 23, 24, 25, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 53, 54, 55, 56, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, - }, - { /* Fourth byte table 98. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 5, 6, - 6, 6, 6, 7, 8, 9, 10, 11, - 12, 13, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, - }, - { /* Fourth byte table 99. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 100. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 101. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 102. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 103. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 36, 36, 36, - 36, 38, 40, 42, 44, 46, 48, 50, - 52, 54, 56, 58, 60, 62, 64, 66, - 68, 70, 72, 74, 76, 78, 80, 82, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, - }, - { /* Fourth byte table 104. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 5, 7, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 27, 29, 31, - 33, 35, 37, 39, 41, 43, 45, 47, - 49, 51, 53, 55, 58, 60, 62, 64, - 66, 68, 70, 72, 74, 76, 78, 80, - 82, 84, 86, 88, 90, 92, 94, 96, - 98, 100, 102, 104, 106, 108, 110, 112, - 114, 116, 118, 120, 123, 125, 127, 129, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, - }, - { /* Fourth byte table 105. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 45, 47, - 49, 51, 53, 55, 57, 59, 61, 63, - 65, 67, 69, 71, 73, 75, 77, 79, - 81, 83, 85, 87, 89, 91, 93, 95, - 97, 99, 101, 103, 105, 107, 110, 112, - 114, 116, 118, 120, 122, 124, 126, 128, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, - }, - { /* Fourth byte table 106. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 33, 35, 37, 39, 41, 43, 45, 47, - 49, 51, 53, 55, 57, 59, 61, 63, - 65, 67, 69, 71, 73, 75, 77, 79, - 81, 83, 85, 87, 89, 91, 93, 95, - 98, 100, 102, 104, 106, 108, 110, 112, - 114, 116, 118, 120, 122, 124, 126, 128, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, - }, - { /* Fourth byte table 107. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 21, 23, 25, 27, 29, 31, - 33, 35, 37, 39, 41, 43, 45, 47, - 49, 51, 53, 55, 57, 59, 61, 63, - 65, 67, 69, 71, 73, 75, 77, 79, - 81, 83, 86, 88, 90, 92, 94, 96, - 98, 100, 102, 104, 106, 108, 110, 112, - 114, 116, 118, 120, 122, 124, 126, 128, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, - }, - { /* Fourth byte table 108. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 9, 11, 13, 15, - 17, 19, 21, 21, 21, 21, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, - }, - { /* Fourth byte table 109. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 9, 13, 17, 21, 25, 29, - 33, 37, 42, 46, 50, 54, 58, 62, - 66, 71, 75, 80, 85, 90, 94, 98, - 102, 106, 110, 114, 118, 122, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, - }, - { /* Fourth byte table 110. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 111. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 112. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 113. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 114. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 115. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 116. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 117. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - }, - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 4, 4, 5, 5, 5, 5, 5, - 8, 8, 8, 9, 10, 13, 15, 15, - 15, 18, 19, 20, 20, 25, 30, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 24, - 28, 32, 36, 40, 44, 48, 52, 56, - 60, 60, 64, 68, 72, 76, 80, 84, - 84, 84, 88, 92, 96, 100, 104, 104, - 104, 108, 112, 116, 120, 124, 128, 128, - 132, 136, 140, 144, 148, 152, 156, 160, - 164, 164, 168, 172, 176, 180, 184, 188, - 188, 188, 192, 196, 200, 204, 208, 208, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 64, 64, 68, 72, 76, 80, 84, - 88, 92, 96, 100, 104, 108, 112, 116, - 120, 124, 128, 132, 136, 140, 144, 144, - 144, 148, 152, 156, 160, 164, 168, 172, - 176, 180, 180, 182, 184, 188, 192, 196, - 200, 200, 204, 208, 212, 216, 220, 224, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, - 227, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 3, 7, 11, 15, 19, - 23, 27, 30, 30, 30, 34, 38, 42, - 46, 50, 54, 54, 54, 58, 62, 66, - 70, 74, 78, 82, 86, 90, 94, 98, - 102, 106, 110, 114, 118, 122, 126, 126, - 126, 130, 134, 138, 142, 146, 150, 154, - 158, 162, 166, 170, 174, 178, 182, 186, - 190, 194, 198, 202, 206, 210, 214, 218, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, - 219, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 12, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 8, 12, - 14, 16, 18, 20, 22, 24, 28, 32, - 36, 40, 44, 48, 52, 56, 62, 68, - 74, 80, 86, 92, 98, 104, 104, 110, - 116, 122, 128, 133, 138, 138, 138, 142, - 146, 150, 154, 158, 162, 168, 174, 179, - 184, 188, 190, 192, 194, 198, 202, 202, - 202, 206, 210, 216, 222, 227, 232, 237, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 112, 112, 116, - 120, 120, 120, 120, 120, 120, 120, 124, - 128, 132, 136, 142, 148, 154, 160, 164, - 168, 174, 180, 184, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, - 188, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 3, 4, 5, 7, 9, 11, - 12, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 18, - 18, 20, 21, 22, 23, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 6, 9, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 17, 17, 17, - 17, 17, 17, 20, 20, 20, 20, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 14, 19, - 22, 27, 32, 37, 37, 42, 42, 47, - 52, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 64, 69, 74, 79, 84, - 89, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 10, 15, 20, 25, - 25, 27, 29, 31, 41, 51, 53, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 57, 59, 61, 61, 63, 65, 65, - 65, 65, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 10, 15, 15, 15, 15, - 20, 20, 20, 20, 20, 25, 30, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 10, 15, 15, 15, 15, - 20, 20, 20, 20, 20, 25, 30, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 40, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 15, 20, 25, 30, 30, 30, 35, - 40, 40, 40, 45, 50, 55, 60, 65, - 70, 70, 70, 75, 80, 85, 90, 95, - 100, 100, 100, 105, 110, 115, 120, 125, - 130, 135, 140, 145, 150, 155, 160, 160, - 160, 165, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - 170, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 10, 15, 20, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 8, - 12, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 7, 7, 7, 7, 7, - 7, 7, 14, 14, 14, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 14, 21, 28, 35, 42, 49, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 21, 28, 28, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 7, 7, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 14, 21, 21, 21, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 7, 14, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 28, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 14, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 7, 7, 7, 7, 7, - 14, 21, 21, 28, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 14, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 7, 14, 24, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 14, 14, - 14, 14, 14, 21, 21, 21, 21, 21, - 28, 28, 28, 28, 28, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 49, 49, 56, 63, - 72, 79, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, - }, - { /* Fourth byte table 36. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 21, 21, - 21, 21, 21, 28, 28, 28, 28, 28, - 35, 35, 35, 35, 35, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, - }, - { /* Fourth byte table 37. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, - }, - { /* Fourth byte table 38. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 39. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 7, 14, 14, 21, 21, 28, 28, 35, - 35, 35, 35, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 49, 49, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, - }, - { /* Fourth byte table 40. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 14, 14, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 41. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 3, 4, - 4, 5, 6, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 16, 17, 19, 20, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 42. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 6, 8, 11, - 12, 13, 14, 16, 18, 20, 21, 21, - 22, 23, 25, 26, 28, 31, 34, 35, - 36, 37, 40, 42, 43, 46, 48, 50, - 52, 54, 56, 57, 58, 59, 60, 62, - 64, 66, 68, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, - }, - { /* Fourth byte table 43. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 3, 5, 7, - 9, 10, 12, 14, 16, 18, 20, 22, - 25, 27, 29, 32, 34, 36, 38, 40, - 42, 44, 46, 48, 50, 52, 54, 56, - 58, 61, 63, 65, 66, 68, 70, 72, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, - }, - { /* Fourth byte table 44. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 21, 21, 21, 21, - 21, 21, 24, 24, 24, 24, 24, 24, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 28, 30, 33, - 33, 33, 33, 33, 33, 33, 33, 33, - 34, 34, 34, 34, 40, 49, 49, 55, - 64, 64, 64, 64, 64, 66, 66, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, - }, - { /* Fourth byte table 45. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 2, 4, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 18, 18, 18, 18, 18, 18, 18, 18, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 20, 21, 21, 21, 22, 23, 24, - 25, 26, 27, 28, 31, 32, 33, 34, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, - }, - { /* Fourth byte table 46. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 14, 15, 16, 17, - 17, 18, 19, 20, 21, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, - 23, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, - }, - { /* Fourth byte table 47. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 7, 10, 10, 13, 16, - 18, 18, 21, 22, 23, 24, 25, 26, - 28, 29, 30, 31, 32, 32, 33, 35, - 35, 35, 36, 37, 38, 39, 40, 40, - 40, 42, 45, 47, 47, 48, 48, 51, - 51, 52, 52, 54, 58, 59, 60, 60, - 61, 62, 63, 63, 64, 65, 67, 69, - 71, 73, 74, 74, 77, 79, 81, 83, - 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, - 85, - }, - { /* Fourth byte table 48. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 3, 3, 3, 4, 5, - 6, 7, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 13, 18, 23, 28, - 33, 38, 43, 48, 53, 58, 63, 68, - 72, 73, 75, 78, 80, 81, 83, 86, - 90, 92, 93, 95, 98, 99, 100, 101, - 102, 103, 105, 108, 110, 111, 113, 116, - 120, 122, 123, 125, 128, 129, 130, 131, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, - }, - { /* Fourth byte table 49. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, - }, - { /* Fourth byte table 50. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6, 12, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, - }, - { /* Fourth byte table 51. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 6, 6, - 6, 6, 12, 12, 12, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 24, 24, 30, - 30, 30, 30, 30, 30, 36, 45, 45, - 51, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, - }, - { /* Fourth byte table 52. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 6, 6, 6, 12, 12, 12, - 18, 18, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 28, 28, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 40, 44, - 48, 54, 60, 60, 60, 66, 72, 72, - 72, 78, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, - }, - { /* Fourth byte table 53. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 12, 12, 18, 24, 24, - 24, 30, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 42, 48, 54, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, - }, - { /* Fourth byte table 54. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 24, 24, 24, - 24, 24, 24, 30, 36, 42, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 55. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, - }, - { /* Fourth byte table 56. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 11, 13, 15, 17, 19, 21, - 23, 25, 27, 29, 31, 34, 37, 40, - 43, 46, 49, 52, 55, 58, 62, 66, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, - }, - { /* Fourth byte table 57. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 53, 56, 59, 62, 65, 68, - 71, 74, 77, 80, 83, 86, 89, 92, - 95, 98, 101, 104, 107, 110, 113, 116, - 119, 122, 125, 128, 131, 134, 137, 140, - 143, 146, 149, 152, 155, 158, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, - }, - { /* Fourth byte table 58. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, - }, - { /* Fourth byte table 59. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, - }, - { /* Fourth byte table 60. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 5, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, - }, - { /* Fourth byte table 61. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, - }, - { /* Fourth byte table 62. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 63. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 64. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 65. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 66. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 67. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 68. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, - }, - { /* Fourth byte table 69. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 4, - 4, 7, 10, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, - }, - { /* Fourth byte table 70. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 7, 14, - 14, 21, 21, 28, 28, 35, 35, 42, - 42, 49, 49, 56, 56, 63, 63, 70, - 70, 77, 77, 84, 84, 84, 91, 91, - 98, 98, 105, 105, 105, 105, 105, 105, - 105, 112, 119, 119, 126, 133, 133, 140, - 147, 147, 154, 161, 161, 168, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, - 175, - }, - { /* Fourth byte table 71. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 7, 7, - 7, 7, 7, 7, 11, 15, 15, 22, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 35, 35, 42, - 42, 49, 49, 56, 56, 63, 63, 70, - 70, 77, 77, 84, 84, 91, 91, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, - }, - { /* Fourth byte table 72. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 7, 14, 14, 14, 21, 21, - 28, 28, 35, 35, 35, 35, 35, 35, - 35, 42, 49, 49, 56, 63, 63, 70, - 77, 77, 84, 91, 91, 98, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 112, 112, 112, - 119, 126, 133, 140, 140, 140, 140, 147, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, - 153, - }, - { /* Fourth byte table 73. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 6, 9, 12, 15, 18, - 21, 24, 27, 30, 33, 36, 39, 42, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, - }, - { /* Fourth byte table 74. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, - }, - { /* Fourth byte table 75. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 45, 45, 45, 48, 51, 54, 57, 60, - 63, 66, 69, 72, 75, 78, 81, 84, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, - }, - { /* Fourth byte table 76. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 15, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 23, 25, 27, 29, 31, 33, 35, - 37, 39, 41, 43, 45, 47, 49, 51, - 53, 56, 59, 62, 65, 68, 71, 74, - 77, 80, 83, 86, 89, 92, 95, 101, - 107, 113, 119, 125, 131, 137, 143, 149, - 155, 161, 167, 173, 179, 194, 206, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, 212, 212, 212, 212, 212, 212, 212, - 212, - }, - { /* Fourth byte table 77. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 149, 151, 153, 155, 157, 159, - 161, 163, 165, 167, 169, 171, 173, 175, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, - 177, - }, - { /* Fourth byte table 78. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 41, 46, 51, 53, 56, 58, - 61, 64, 67, 70, 73, 76, 79, 82, - 85, 88, 91, 94, 97, 100, 103, 106, - 109, 112, 115, 118, 121, 124, 127, 130, - 133, 136, 139, 142, 145, 148, 151, 154, - 157, 160, 163, 166, 169, 172, 175, 178, - 181, 184, 187, 190, 193, 196, 199, 202, - 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, - 202, - }, - { /* Fourth byte table 79. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 7, 9, 11, 13, 15, - 17, 20, 24, 26, 28, 31, 34, 36, - 38, 40, 43, 46, 49, 52, 55, 57, - 59, 61, 63, 65, 68, 70, 72, 74, - 77, 80, 82, 85, 88, 91, 93, 96, - 101, 107, 109, 112, 115, 118, 121, 128, - 136, 138, 140, 143, 145, 147, 149, 152, - 154, 156, 158, 160, 162, 165, 167, 169, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, - 171, - }, - { /* Fourth byte table 80. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 10, 12, 14, 16, 22, - 25, 27, 29, 31, 33, 35, 37, 39, - 41, 43, 45, 48, 50, 52, 55, 58, - 60, 64, 67, 69, 71, 73, 75, 80, - 85, 89, 93, 97, 101, 105, 109, 113, - 117, 121, 126, 131, 136, 141, 146, 151, - 156, 161, 166, 171, 176, 181, 186, 191, - 196, 201, 206, 211, 216, 221, 226, 231, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, - }, - { /* Fourth byte table 81. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 56, - 56, 60, 60, 64, 64, 64, 68, 72, - 76, 80, 84, 88, 92, 96, 100, 104, - 104, 108, 108, 112, 112, 112, 116, 120, - 120, 120, 120, 124, 128, 132, 136, 136, - 136, 140, 144, 148, 152, 156, 160, 164, - 168, 172, 176, 180, 184, 188, 192, 196, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, - }, - { /* Fourth byte table 82. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 172, 172, 172, 172, - 172, 176, 180, 184, 188, 192, 196, 200, - 204, 208, 212, 216, 220, 224, 228, 232, - 236, 236, 236, 236, 236, 236, 236, 236, - 236, 236, 236, 236, 236, 236, 236, 236, - 236, 236, 236, 236, 236, 236, 236, 236, - 236, 236, 236, 236, 236, 236, 236, 236, - 236, 236, 236, 236, 236, 236, 236, 236, - 236, 236, 236, 236, 236, 236, 236, 236, - 236, 236, 236, 236, 236, 236, 236, 236, - 236, 236, 236, 236, 236, 236, 236, 236, - 236, - }, - { /* Fourth byte table 83. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 65, 70, 75, 79, 83, 87, 92, 97, - 102, 106, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, - 110, - }, - { /* Fourth byte table 84. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 9, 12, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 20, 24, 28, 32, - 36, 36, 36, 36, 36, 36, 41, 41, - 46, 48, 50, 52, 54, 56, 58, 60, - 62, 64, 65, 70, 75, 82, 89, 94, - 99, 104, 109, 114, 119, 124, 129, 134, - 134, 139, 144, 149, 154, 159, 159, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, - }, - { /* Fourth byte table 85. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 10, 15, 20, 20, 25, - 30, 35, 40, 45, 50, 55, 60, 65, - 69, 71, 73, 75, 77, 79, 81, 83, - 85, 87, 89, 91, 93, 95, 97, 99, - 101, 103, 105, 107, 109, 111, 113, 115, - 117, 119, 121, 123, 125, 127, 129, 131, - 133, 135, 137, 139, 141, 143, 145, 147, - 149, 151, 153, 155, 157, 159, 161, 163, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, - 165, - }, - { /* Fourth byte table 86. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - 64, 66, 68, 70, 72, 76, 80, 82, - 84, 86, 88, 90, 92, 94, 96, 98, - 100, 104, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, - 108, - }, - { /* Fourth byte table 87. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 4, 6, 8, - 10, 12, 14, 16, 18, 20, 24, 26, - 28, 30, 32, 34, 36, 38, 40, 42, - 44, 46, 48, 54, 60, 66, 72, 78, - 84, 90, 96, 102, 108, 114, 120, 126, - 132, 138, 144, 150, 156, 158, 160, 162, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, - }, - { /* Fourth byte table 88. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, - 248, - }, - { /* Fourth byte table 89. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 36, 42, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 54, 60, 68, 76, 84, 92, 100, - 108, 116, 122, 155, 170, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, - 178, - }, - { /* Fourth byte table 90. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 4, 7, 8, 9, 10, 11, - 14, 17, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 22, 25, 28, 29, 30, 31, 32, - 33, 34, 37, 40, 43, 46, 49, 52, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, - }, - { /* Fourth byte table 91. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 15, 15, - 16, 17, 20, 23, 26, 29, 30, 31, - 32, 33, 36, 37, 37, 38, 39, 40, - 41, 44, 45, 46, 47, 48, 51, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 62, 63, 64, 65, 66, 66, 66, 66, - 66, 69, 73, 76, 76, 79, 79, 82, - 86, 89, 93, 96, 100, 103, 107, 110, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, - }, - { /* Fourth byte table 92. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 6, 10, 14, 18, 22, 26, - 30, 34, 38, 42, 46, 50, 52, 54, - 56, 58, 60, 62, 64, 66, 68, 70, - 72, 74, 76, 78, 80, 82, 84, 86, - 88, 90, 92, 94, 96, 98, 100, 102, - 104, 106, 108, 110, 112, 114, 116, 118, - 120, 122, 124, 126, 128, 130, 132, 134, - 136, 138, 140, 142, 144, 146, 148, 150, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, - }, - { /* Fourth byte table 93. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - 64, 66, 68, 70, 72, 74, 76, 78, - 80, 82, 84, 86, 88, 90, 92, 94, - 96, 98, 100, 102, 104, 106, 112, 118, - 124, 130, 136, 142, 146, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, - 150, - }, - { /* Fourth byte table 94. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 95. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 34, 37, 40, 43, 46, 49, 52, 55, - 58, 61, 64, 67, 70, 73, 76, 79, - 82, 85, 88, 91, 94, 97, 100, 103, - 106, 109, 112, 115, 118, 121, 124, 127, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, - }, - { /* Fourth byte table 96. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 144, 147, 150, 153, 156, 159, 162, 165, - 168, 171, 174, 177, 180, 183, 186, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, - 189, - }, - { /* Fourth byte table 97. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 6, 9, 12, 15, - 18, 18, 18, 21, 24, 27, 30, 33, - 36, 36, 36, 39, 42, 45, 48, 51, - 54, 54, 54, 57, 60, 63, 63, 63, - 63, 65, 67, 69, 72, 74, 76, 79, - 79, 82, 85, 88, 91, 94, 97, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, - 100, - }, - { /* Fourth byte table 98. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, - 18, 31, 44, 57, 70, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, - }, - { /* Fourth byte table 99. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 18, 31, 44, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, - }, - { /* Fourth byte table 100. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, - }, - { /* Fourth byte table 101. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 102. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 103. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 29, 30, - 31, 31, 31, 32, 32, 32, 33, 34, - 34, 34, 35, 36, 37, 38, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 50, 51, 51, 52, 53, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, - }, - { /* Fourth byte table 104. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 105. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 6, - 7, 8, 9, 10, 10, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 18, 19, - 20, 21, 22, 23, 24, 25, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 53, 54, 55, 56, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, - }, - { /* Fourth byte table 106. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 5, 6, - 6, 6, 6, 7, 8, 9, 10, 11, - 12, 13, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, - }, - { /* Fourth byte table 107. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 108. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 109. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 110. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 111. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 38, 40, 40, - 40, 42, 44, 46, 48, 50, 52, 54, - 56, 58, 60, 62, 64, 66, 68, 70, - 72, 74, 76, 78, 80, 82, 84, 86, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, - }, - { /* Fourth byte table 112. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 5, 7, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 27, 29, 31, - 33, 35, 37, 39, 41, 43, 45, 47, - 49, 51, 53, 55, 58, 60, 62, 64, - 66, 68, 70, 72, 74, 76, 78, 80, - 82, 84, 86, 88, 90, 92, 94, 96, - 98, 100, 102, 104, 106, 108, 110, 112, - 114, 116, 118, 120, 123, 125, 127, 129, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, - }, - { /* Fourth byte table 113. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 45, 47, - 49, 51, 53, 55, 57, 59, 61, 63, - 65, 67, 69, 71, 73, 75, 77, 79, - 81, 83, 85, 87, 89, 91, 93, 95, - 97, 99, 101, 103, 105, 107, 110, 112, - 114, 116, 118, 120, 122, 124, 126, 128, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, - }, - { /* Fourth byte table 114. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 33, 35, 37, 39, 41, 43, 45, 47, - 49, 51, 53, 55, 57, 59, 61, 63, - 65, 67, 69, 71, 73, 75, 77, 79, - 81, 83, 85, 87, 89, 91, 93, 95, - 98, 100, 102, 104, 106, 108, 110, 112, - 114, 116, 118, 120, 122, 124, 126, 128, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, - }, - { /* Fourth byte table 115. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 21, 23, 25, 27, 29, 31, - 33, 35, 37, 39, 41, 43, 45, 47, - 49, 51, 53, 55, 57, 59, 61, 63, - 65, 67, 69, 71, 73, 75, 77, 79, - 81, 83, 86, 88, 90, 92, 94, 96, - 98, 100, 102, 104, 106, 108, 110, 112, - 114, 116, 118, 120, 122, 124, 126, 128, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 130, 130, 130, 130, 130, 130, - 130, - }, - { /* Fourth byte table 116. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 25, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, - }, - { /* Fourth byte table 117. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 9, 13, 17, 21, 25, 29, - 33, 37, 42, 46, 50, 54, 58, 62, - 66, 71, 75, 80, 85, 90, 94, 98, - 102, 106, 110, 114, 118, 122, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, - 127, - }, - }, -}; - -static const uint16_t u8_decomp_b4_16bit_tbl[2][30][257] = { - { - { /* Fourth byte 16-bit table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 38, 44, 48, 52, 56, 60, 64, - 68, 72, 76, 80, 84, 90, 96, 102, - 108, 112, 116, 120, 124, 130, 136, 140, - 144, 148, 152, 156, 160, 164, 168, 172, - 176, 180, 184, 188, 192, 196, 200, 206, - 212, 216, 220, 224, 228, 232, 236, 240, - 244, 250, 256, 260, 264, 268, 272, 276, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, - }, - { /* Fourth byte 16-bit table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 54, 60, 66, - 72, 78, 84, 90, 96, 100, 104, 108, - 112, 116, 120, 124, 128, 134, 140, 144, - 148, 152, 156, 160, 164, 170, 176, 182, - 188, 194, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 262, 268, 274, 280, 284, 288, 292, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, - }, - { /* Fourth byte 16-bit table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 107, 116, 116, 116, 116, - 116, 120, 124, 128, 132, 138, 144, 150, - 156, 162, 168, 174, 180, 186, 192, 198, - 204, 210, 216, 222, 228, 234, 240, 246, - 252, 256, 260, 264, 268, 272, 276, 282, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, - }, - { /* Fourth byte 16-bit table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 36, 42, - 48, 52, 56, 60, 64, 68, 72, 76, - 80, 86, 92, 98, 104, 110, 116, 122, - 128, 134, 140, 146, 152, 158, 164, 170, - 176, 182, 188, 194, 200, 204, 208, 212, - 216, 222, 228, 234, 240, 246, 252, 258, - 264, 270, 276, 280, 284, 288, 292, 296, - 300, 304, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, - }, - { /* Fourth byte 16-bit table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 17, 24, 31, 38, 45, - 52, 57, 62, 69, 76, 83, 90, 97, - 104, 109, 114, 121, 128, 135, 142, 142, - 142, 147, 152, 159, 166, 173, 180, 180, - 180, 185, 190, 197, 204, 211, 218, 225, - 232, 237, 242, 249, 256, 263, 270, 277, - 284, 289, 294, 301, 308, 315, 322, 329, - 336, 341, 346, 353, 360, 367, 374, 381, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, - }, - { /* Fourth byte 16-bit table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 17, 24, 31, 38, 38, - 38, 43, 48, 55, 62, 69, 76, 76, - 76, 81, 86, 93, 100, 107, 114, 121, - 128, 128, 133, 133, 140, 140, 147, 147, - 154, 159, 164, 171, 178, 185, 192, 199, - 206, 211, 216, 223, 230, 237, 244, 251, - 258, 263, 268, 273, 278, 283, 288, 293, - 298, 303, 308, 313, 318, 323, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, - }, - { /* Fourth byte 16-bit table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 14, 23, 32, 41, 50, 59, - 68, 75, 82, 91, 100, 109, 118, 127, - 136, 143, 150, 159, 168, 177, 186, 195, - 204, 211, 218, 227, 236, 245, 254, 263, - 272, 279, 286, 295, 304, 313, 322, 331, - 340, 347, 354, 363, 372, 381, 390, 399, - 408, 413, 418, 425, 430, 437, 437, 442, - 449, 454, 459, 464, 469, 474, 477, 480, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, - }, - { /* Fourth byte 16-bit table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 14, 21, 26, 33, 33, 38, - 45, 50, 55, 60, 65, 70, 82, 94, - 106, 111, 116, 123, 130, 130, 130, 135, - 142, 147, 152, 157, 162, 162, 174, 186, - 198, 203, 208, 215, 222, 227, 232, 237, - 244, 249, 254, 259, 264, 269, 280, 291, - 293, 293, 293, 300, 305, 312, 312, 317, - 324, 329, 334, 339, 344, 349, 356, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, - }, - { /* Fourth byte 16-bit table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 15, 20, 25, 30, 35, - 40, 45, 50, 55, 60, 65, 70, 78, - 86, 94, 102, 110, 118, 126, 134, 142, - 150, 158, 166, 174, 182, 190, 190, 190, - 190, 195, 200, 205, 210, 215, 220, 225, - 230, 235, 240, 245, 250, 255, 260, 265, - 270, 275, 280, 285, 290, 295, 300, 305, - 310, 315, 320, 325, 330, 335, 340, 345, - 350, 350, 350, 350, 350, 350, 350, 350, - 350, 350, 350, 350, 350, 350, 350, 350, - 350, 350, 350, 350, 350, 350, 350, 350, - 350, 350, 350, 350, 350, 350, 350, 350, - 350, 350, 350, 350, 350, 350, 350, 350, - 350, 350, 350, 350, 350, 350, 350, 350, - 350, 350, 350, 350, 350, 350, 350, 350, - 350, 350, 350, 350, 350, 350, 350, 350, - 350, - }, - { /* Fourth byte 16-bit table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 27, 42, 51, 66, 75, 84, - 102, 114, 123, 132, 141, 153, 165, 177, - 189, 201, 213, 225, 243, 249, 267, 285, - 300, 312, 330, 348, 360, 369, 378, 390, - 402, 417, 432, 441, 450, 462, 471, 480, - 486, 492, 501, 510, 528, 540, 555, 573, - 585, 594, 603, 621, 633, 651, 660, 675, - 684, 696, 705, 717, 732, 744, 759, 771, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, - }, - { /* Fourth byte 16-bit table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 24, 33, 45, 54, 63, 72, - 87, 99, 105, 123, 132, 147, 159, 171, - 180, 189, 201, 207, 219, 234, 240, 258, - 267, 271, 275, 279, 283, 287, 291, 295, - 299, 303, 307, 312, 317, 322, 327, 332, - 337, 342, 347, 352, 357, 362, 367, 372, - 377, 382, 385, 387, 389, 392, 394, 396, - 396, 396, 396, 396, 402, 408, 414, 420, - 432, 432, 432, 432, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 432, 432, - 432, - }, - { /* Fourth byte 16-bit table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 34, 38, - 42, 46, 50, 54, 58, 62, 66, 70, - 74, 78, 82, 86, 90, 94, 98, 102, - 106, 110, 114, 118, 122, 126, 130, 134, - 138, 142, 146, 150, 154, 158, 162, 166, - 170, 174, 178, 182, 186, 190, 194, 198, - 202, 206, 210, 214, 218, 222, 226, 230, - 234, 238, 242, 246, 250, 254, 258, 262, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, - }, - { /* Fourth byte 16-bit table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 125, - 130, 135, 140, 145, 150, 156, 162, 168, - 174, 180, 186, 190, 194, 198, 202, 206, - 210, 214, 218, 222, 226, 230, 234, 238, - 242, 246, 250, 254, 258, 262, 266, 270, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, - }, - { /* Fourth byte 16-bit table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 98, 104, 110, 116, 122, 126, 130, 134, - 138, 142, 146, 150, 154, 158, 162, 166, - 170, 174, 178, 182, 186, 190, 194, 198, - 202, 206, 210, 214, 218, 222, 226, 230, - 234, 238, 242, 246, 250, 254, 258, 262, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, - }, - { /* Fourth byte 16-bit table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 130, 136, 140, 144, 148, 152, 156, 160, - 164, 168, 172, 176, 180, 184, 188, 192, - 196, 200, 204, 210, 216, 222, 226, 230, - 234, 238, 242, 246, 250, 254, 258, 262, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, - }, - { /* Fourth byte 16-bit table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 36, 42, - 48, 54, 60, 66, 72, 78, 84, 90, - 96, 102, 108, 114, 120, 126, 132, 138, - 144, 150, 156, 162, 168, 174, 180, 186, - 192, 198, 204, 210, 216, 222, 228, 234, - 240, 246, 252, 258, 264, 270, 276, 282, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, - }, - { /* Fourth byte 16-bit table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 36, 42, - 48, 54, 60, 66, 72, 78, 84, 90, - 96, 96, 96, 102, 108, 114, 120, 126, - 132, 138, 144, 150, 156, 162, 168, 174, - 180, 186, 192, 198, 204, 210, 216, 222, - 228, 234, 240, 246, 252, 258, 264, 270, - 276, 282, 288, 294, 300, 306, 312, 318, - 324, 330, 336, 342, 348, 354, 360, 366, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, - }, - { /* Fourth byte 16-bit table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 17, 21, 25, 29, - 33, 37, 41, 45, 49, 53, 58, 62, - 66, 70, 74, 79, 83, 87, 91, 96, - 100, 104, 108, 112, 116, 121, 125, 129, - 133, 137, 141, 145, 149, 153, 157, 161, - 165, 169, 173, 177, 181, 185, 189, 193, - 197, 201, 205, 209, 213, 218, 222, 226, - 230, 235, 239, 243, 247, 251, 255, 259, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, - }, - { /* Fourth byte 16-bit table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 105, 109, 113, 117, 121, 125, - 129, 134, 139, 143, 147, 151, 155, 159, - 163, 167, 171, 175, 179, 184, 188, 192, - 196, 200, 205, 209, 213, 217, 221, 225, - 229, 233, 237, 241, 246, 250, 255, 259, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, - }, - { /* Fourth byte 16-bit table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 41, 45, 49, 53, 57, 61, - 66, 70, 75, 80, 84, 88, 92, 96, - 101, 106, 110, 114, 118, 122, 126, 130, - 134, 138, 142, 146, 150, 155, 159, 163, - 167, 171, 175, 179, 183, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, - 231, 236, 240, 244, 248, 252, 256, 261, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, - }, - { /* Fourth byte 16-bit table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 45, 49, 53, 57, 61, - 65, 69, 73, 77, 81, 85, 89, 93, - 97, 101, 105, 109, 113, 117, 122, 126, - 130, 134, 138, 142, 147, 151, 155, 159, - 163, 167, 171, 175, 179, 184, 188, 192, - 196, 201, 205, 209, 213, 217, 221, 225, - 230, 235, 240, 244, 249, 253, 257, 261, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, - }, - { /* Fourth byte 16-bit table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 29, - 33, 37, 41, 45, 49, 53, 58, 62, - 66, 71, 76, 80, 84, 88, 92, 96, - 100, 104, 108, 112, 117, 121, 126, 130, - 135, 139, 143, 147, 152, 156, 160, 165, - 170, 174, 178, 182, 186, 190, 194, 198, - 202, 206, 210, 214, 218, 222, 227, 231, - 236, 240, 245, 249, 254, 259, 264, 268, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, - }, - { /* Fourth byte 16-bit table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 9, 14, 19, 24, 28, 32, - 36, 40, 44, 48, 52, 56, 61, 65, - 69, 73, 77, 82, 86, 91, 96, 100, - 104, 108, 112, 116, 120, 125, 130, 135, - 139, 143, 148, 152, 156, 160, 165, 169, - 173, 177, 181, 185, 190, 194, 198, 202, - 206, 210, 214, 219, 224, 228, 233, 237, - 242, 246, 250, 254, 259, 264, 268, 273, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, - }, - { /* Fourth byte 16-bit table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 9, 13, 17, 21, 25, 29, - 34, 39, 44, 49, 53, 57, 61, 65, - 69, 73, 77, 81, 85, 89, 93, 97, - 102, 106, 110, 114, 118, 122, 126, 130, - 134, 138, 142, 146, 150, 155, 160, 165, - 169, 173, 177, 181, 186, 190, 195, 199, - 203, 208, 213, 217, 221, 225, 229, 233, - 237, 241, 245, 249, 253, 257, 261, 265, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, - }, - { /* Fourth byte 16-bit table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 25, 29, - 33, 37, 41, 45, 50, 55, 59, 63, - 67, 71, 75, 79, 84, 88, 92, 96, - 100, 105, 110, 114, 118, 122, 127, 131, - 135, 140, 145, 149, 153, 157, 162, 166, - 170, 174, 178, 182, 186, 190, 195, 199, - 203, 207, 212, 216, 220, 224, 228, 233, - 238, 242, 246, 250, 255, 259, 264, 268, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, - }, - { /* Fourth byte 16-bit table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - }, - { - { /* Fourth byte 16-bit table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 38, 44, 48, 52, 56, 60, 64, - 68, 72, 76, 80, 84, 90, 96, 102, - 108, 112, 116, 120, 124, 130, 136, 140, - 144, 148, 152, 156, 160, 164, 168, 172, - 176, 180, 184, 188, 192, 196, 200, 206, - 212, 216, 220, 224, 228, 232, 236, 240, - 244, 250, 256, 260, 264, 268, 272, 276, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, - 280, - }, - { /* Fourth byte 16-bit table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 54, 60, 66, - 72, 78, 84, 90, 96, 100, 104, 108, - 112, 116, 120, 124, 128, 134, 140, 144, - 148, 152, 156, 160, 164, 170, 176, 182, - 188, 194, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 262, 268, 274, 280, 284, 288, 292, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, - }, - { /* Fourth byte 16-bit table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 107, 116, 116, 116, 116, - 116, 120, 124, 128, 132, 138, 144, 150, - 156, 162, 168, 174, 180, 186, 192, 198, - 204, 210, 216, 222, 228, 234, 240, 246, - 252, 256, 260, 264, 268, 272, 276, 282, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, - }, - { /* Fourth byte 16-bit table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 36, 42, - 48, 52, 56, 60, 64, 68, 72, 76, - 80, 86, 92, 98, 104, 110, 116, 122, - 128, 134, 140, 146, 152, 158, 164, 170, - 176, 182, 188, 194, 200, 204, 208, 212, - 216, 222, 228, 234, 240, 246, 252, 258, - 264, 270, 276, 280, 284, 288, 292, 296, - 300, 304, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, - 308, - }, - { /* Fourth byte 16-bit table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 17, 24, 31, 38, 45, - 52, 57, 62, 69, 76, 83, 90, 97, - 104, 109, 114, 121, 128, 135, 142, 142, - 142, 147, 152, 159, 166, 173, 180, 180, - 180, 185, 190, 197, 204, 211, 218, 225, - 232, 237, 242, 249, 256, 263, 270, 277, - 284, 289, 294, 301, 308, 315, 322, 329, - 336, 341, 346, 353, 360, 367, 374, 381, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, - 388, - }, - { /* Fourth byte 16-bit table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 17, 24, 31, 38, 38, - 38, 43, 48, 55, 62, 69, 76, 76, - 76, 81, 86, 93, 100, 107, 114, 121, - 128, 128, 133, 133, 140, 140, 147, 147, - 154, 159, 164, 171, 178, 185, 192, 199, - 206, 211, 216, 223, 230, 237, 244, 251, - 258, 263, 268, 273, 278, 283, 288, 293, - 298, 303, 308, 313, 318, 323, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, - 328, - }, - { /* Fourth byte 16-bit table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 14, 23, 32, 41, 50, 59, - 68, 75, 82, 91, 100, 109, 118, 127, - 136, 143, 150, 159, 168, 177, 186, 195, - 204, 211, 218, 227, 236, 245, 254, 263, - 272, 279, 286, 295, 304, 313, 322, 331, - 340, 347, 354, 363, 372, 381, 390, 399, - 408, 413, 418, 425, 430, 437, 437, 442, - 449, 454, 459, 464, 469, 474, 477, 480, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, - }, - { /* Fourth byte 16-bit table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 14, 21, 26, 33, 33, 38, - 45, 50, 55, 60, 65, 70, 82, 94, - 106, 111, 116, 123, 130, 130, 130, 135, - 142, 147, 152, 157, 162, 162, 174, 186, - 198, 203, 208, 215, 222, 227, 232, 237, - 244, 249, 254, 259, 264, 269, 280, 291, - 293, 293, 293, 300, 305, 312, 312, 317, - 324, 329, 334, 339, 344, 349, 356, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, - 359, - }, - { /* Fourth byte 16-bit table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 10, 15, 20, 25, 30, 35, - 40, 45, 50, 55, 60, 65, 70, 78, - 86, 94, 102, 110, 118, 126, 134, 142, - 150, 158, 166, 174, 182, 190, 207, 221, - 221, 226, 231, 236, 241, 246, 251, 256, - 261, 266, 271, 276, 281, 286, 291, 296, - 301, 306, 311, 316, 321, 326, 331, 336, - 341, 346, 351, 356, 361, 366, 371, 376, - 381, 381, 381, 381, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 381, 381, 381, - 381, - }, - { /* Fourth byte 16-bit table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 27, 42, 51, 66, 75, 84, - 102, 114, 123, 132, 141, 153, 165, 177, - 189, 201, 213, 225, 243, 249, 267, 285, - 300, 312, 330, 348, 360, 369, 378, 390, - 402, 417, 432, 441, 450, 462, 471, 480, - 486, 492, 501, 510, 528, 540, 555, 573, - 585, 594, 603, 621, 633, 651, 660, 675, - 684, 696, 705, 717, 732, 744, 759, 771, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 777, 777, 777, - 777, - }, - { /* Fourth byte 16-bit table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 24, 33, 45, 54, 63, 72, - 87, 99, 105, 123, 132, 147, 159, 171, - 180, 189, 201, 207, 219, 234, 240, 258, - 267, 271, 275, 279, 283, 287, 291, 295, - 299, 303, 307, 312, 317, 322, 327, 332, - 337, 342, 347, 352, 357, 362, 367, 372, - 377, 382, 385, 387, 389, 392, 394, 396, - 398, 401, 404, 406, 412, 418, 424, 430, - 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, - 442, - }, - { /* Fourth byte 16-bit table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 164, 168, 172, 176, 180, 184, 188, - 192, 196, 200, 204, 208, 212, 216, 220, - 224, 228, 232, 236, 240, 244, 248, 252, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, - 256, - }, - { /* Fourth byte 16-bit table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 34, 38, - 42, 46, 50, 54, 58, 62, 66, 70, - 74, 78, 82, 86, 90, 94, 98, 102, - 106, 110, 114, 118, 122, 126, 130, 134, - 138, 142, 146, 150, 154, 158, 162, 166, - 170, 174, 178, 182, 186, 190, 194, 198, - 202, 206, 210, 214, 218, 222, 226, 230, - 234, 238, 242, 246, 250, 254, 258, 262, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, - }, - { /* Fourth byte 16-bit table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 125, - 130, 135, 140, 145, 150, 156, 162, 168, - 174, 180, 186, 190, 194, 198, 202, 206, - 210, 214, 218, 222, 226, 230, 234, 238, - 242, 246, 250, 254, 258, 262, 266, 270, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, - 274, - }, - { /* Fourth byte 16-bit table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 98, 104, 110, 116, 122, 126, 130, 134, - 138, 142, 146, 150, 154, 158, 162, 166, - 170, 174, 178, 182, 186, 190, 194, 198, - 202, 206, 210, 214, 218, 222, 226, 230, - 234, 238, 242, 246, 250, 254, 258, 262, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, - }, - { /* Fourth byte 16-bit table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 130, 136, 140, 144, 148, 152, 156, 160, - 164, 168, 172, 176, 180, 184, 188, 192, - 196, 200, 204, 210, 216, 222, 226, 230, - 234, 238, 242, 246, 250, 254, 258, 262, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 266, - 266, - }, - { /* Fourth byte 16-bit table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 36, 42, - 48, 54, 60, 66, 72, 78, 84, 90, - 96, 102, 108, 114, 120, 126, 132, 138, - 144, 150, 156, 162, 168, 174, 180, 186, - 192, 198, 204, 210, 216, 222, 228, 234, - 240, 246, 252, 258, 264, 270, 276, 282, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, - 288, - }, - { /* Fourth byte 16-bit table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 12, 18, 24, 30, 36, 42, - 48, 54, 60, 66, 72, 78, 84, 90, - 96, 96, 96, 102, 108, 114, 120, 126, - 132, 138, 144, 150, 156, 162, 168, 174, - 180, 186, 192, 198, 204, 210, 216, 222, - 228, 234, 240, 246, 252, 258, 264, 270, - 276, 282, 288, 294, 300, 306, 312, 318, - 324, 330, 336, 342, 348, 354, 360, 366, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, - 372, - }, - { /* Fourth byte 16-bit table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 17, 21, 25, 29, - 33, 37, 41, 45, 49, 53, 58, 62, - 66, 70, 74, 79, 83, 87, 91, 96, - 100, 104, 108, 112, 116, 121, 125, 129, - 133, 137, 141, 145, 149, 153, 157, 161, - 165, 169, 173, 177, 181, 185, 189, 193, - 197, 201, 205, 209, 213, 218, 222, 226, - 230, 235, 239, 243, 247, 251, 255, 259, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, - }, - { /* Fourth byte 16-bit table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 105, 109, 113, 117, 121, 125, - 129, 134, 139, 143, 147, 151, 155, 159, - 163, 167, 171, 175, 179, 184, 188, 192, - 196, 200, 205, 209, 213, 217, 221, 225, - 229, 233, 237, 241, 246, 250, 255, 259, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 263, 263, 263, 263, - 263, - }, - { /* Fourth byte 16-bit table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 41, 45, 49, 53, 57, 61, - 66, 70, 75, 80, 84, 88, 92, 96, - 101, 106, 110, 114, 118, 122, 126, 130, - 134, 138, 142, 146, 150, 155, 159, 163, - 167, 171, 175, 179, 183, 187, 191, 195, - 199, 203, 207, 211, 215, 219, 223, 227, - 231, 236, 240, 244, 248, 252, 256, 261, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, - }, - { /* Fourth byte 16-bit table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 45, 49, 53, 57, 61, - 65, 69, 73, 77, 81, 85, 89, 93, - 97, 101, 105, 109, 113, 117, 122, 126, - 130, 134, 138, 142, 147, 151, 155, 159, - 163, 167, 171, 175, 179, 184, 188, 192, - 196, 201, 205, 209, 213, 217, 221, 225, - 230, 235, 240, 244, 249, 253, 257, 261, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, - 265, - }, - { /* Fourth byte 16-bit table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 29, - 33, 37, 41, 45, 49, 53, 58, 62, - 66, 71, 76, 80, 84, 88, 92, 96, - 100, 104, 108, 112, 117, 121, 126, 130, - 135, 139, 143, 147, 152, 156, 160, 165, - 170, 174, 178, 182, 186, 190, 194, 198, - 202, 206, 210, 214, 218, 222, 227, 231, - 236, 240, 245, 249, 254, 259, 264, 268, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, - }, - { /* Fourth byte 16-bit table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 9, 14, 19, 24, 28, 32, - 36, 40, 44, 48, 52, 56, 61, 65, - 69, 73, 77, 82, 86, 91, 96, 100, - 104, 108, 112, 116, 120, 125, 130, 135, - 139, 143, 148, 152, 156, 160, 165, 169, - 173, 177, 181, 185, 190, 194, 198, 202, - 206, 210, 214, 219, 224, 228, 233, 237, - 242, 246, 250, 254, 259, 264, 268, 273, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, - 277, - }, - { /* Fourth byte 16-bit table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 9, 13, 17, 21, 25, 29, - 34, 39, 44, 49, 53, 57, 61, 65, - 69, 73, 77, 81, 85, 89, 93, 97, - 102, 106, 110, 114, 118, 122, 126, 130, - 134, 138, 142, 146, 150, 155, 160, 165, - 169, 173, 177, 181, 186, 190, 195, 199, - 203, 208, 213, 217, 221, 225, 229, 233, - 237, 241, 245, 249, 253, 257, 261, 265, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, - }, - { /* Fourth byte 16-bit table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 25, 29, - 33, 37, 41, 45, 50, 55, 59, 63, - 67, 71, 75, 79, 84, 88, 92, 96, - 100, 105, 110, 114, 118, 122, 127, 131, - 135, 140, 145, 149, 153, 157, 162, 166, - 170, 174, 178, 182, 186, 190, 195, 199, - 203, 207, 212, 216, 220, 224, 228, 233, - 238, 242, 246, 250, 255, 259, 264, 268, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, - 272, - }, - }, -}; - -static const uchar_t u8_decomp_final_tbl[2][19370] = { - { - 0x20, 0x20, 0xCC, 0x88, 0x61, 0x20, 0xCC, 0x84, - 0x32, 0x33, 0x20, 0xCC, 0x81, 0xCE, 0xBC, 0x20, - 0xCC, 0xA7, 0x31, 0x6F, 0x31, 0xE2, 0x81, 0x84, - 0x34, 0x31, 0xE2, 0x81, 0x84, 0x32, 0x33, 0xE2, - 0x81, 0x84, 0x34, 0xF6, 0x41, 0xCC, 0x80, 0xF6, - 0x41, 0xCC, 0x81, 0xF6, 0x41, 0xCC, 0x82, 0xF6, - 0x41, 0xCC, 0x83, 0xF6, 0x41, 0xCC, 0x88, 0xF6, - 0x41, 0xCC, 0x8A, 0xF6, 0x43, 0xCC, 0xA7, 0xF6, - 0x45, 0xCC, 0x80, 0xF6, 0x45, 0xCC, 0x81, 0xF6, - 0x45, 0xCC, 0x82, 0xF6, 0x45, 0xCC, 0x88, 0xF6, - 0x49, 0xCC, 0x80, 0xF6, 0x49, 0xCC, 0x81, 0xF6, - 0x49, 0xCC, 0x82, 0xF6, 0x49, 0xCC, 0x88, 0xF6, - 0x4E, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x80, 0xF6, - 0x4F, 0xCC, 0x81, 0xF6, 0x4F, 0xCC, 0x82, 0xF6, - 0x4F, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x88, 0xF6, - 0x55, 0xCC, 0x80, 0xF6, 0x55, 0xCC, 0x81, 0xF6, - 0x55, 0xCC, 0x82, 0xF6, 0x55, 0xCC, 0x88, 0xF6, - 0x59, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x80, 0xF6, - 0x61, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x82, 0xF6, - 0x61, 0xCC, 0x83, 0xF6, 0x61, 0xCC, 0x88, 0xF6, - 0x61, 0xCC, 0x8A, 0xF6, 0x63, 0xCC, 0xA7, 0xF6, - 0x65, 0xCC, 0x80, 0xF6, 0x65, 0xCC, 0x81, 0xF6, - 0x65, 0xCC, 0x82, 0xF6, 0x65, 0xCC, 0x88, 0xF6, - 0x69, 0xCC, 0x80, 0xF6, 0x69, 0xCC, 0x81, 0xF6, - 0x69, 0xCC, 0x82, 0xF6, 0x69, 0xCC, 0x88, 0xF6, - 0x6E, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x80, 0xF6, - 0x6F, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x82, 0xF6, - 0x6F, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x88, 0xF6, - 0x75, 0xCC, 0x80, 0xF6, 0x75, 0xCC, 0x81, 0xF6, - 0x75, 0xCC, 0x82, 0xF6, 0x75, 0xCC, 0x88, 0xF6, - 0x79, 0xCC, 0x81, 0xF6, 0x79, 0xCC, 0x88, 0xF6, - 0x41, 0xCC, 0x84, 0xF6, 0x61, 0xCC, 0x84, 0xF6, - 0x41, 0xCC, 0x86, 0xF6, 0x61, 0xCC, 0x86, 0xF6, - 0x41, 0xCC, 0xA8, 0xF6, 0x61, 0xCC, 0xA8, 0xF6, - 0x43, 0xCC, 0x81, 0xF6, 0x63, 0xCC, 0x81, 0xF6, - 0x43, 0xCC, 0x82, 0xF6, 0x63, 0xCC, 0x82, 0xF6, - 0x43, 0xCC, 0x87, 0xF6, 0x63, 0xCC, 0x87, 0xF6, - 0x43, 0xCC, 0x8C, 0xF6, 0x63, 0xCC, 0x8C, 0xF6, - 0x44, 0xCC, 0x8C, 0xF6, 0x64, 0xCC, 0x8C, 0xF6, - 0x45, 0xCC, 0x84, 0xF6, 0x65, 0xCC, 0x84, 0xF6, - 0x45, 0xCC, 0x86, 0xF6, 0x65, 0xCC, 0x86, 0xF6, - 0x45, 0xCC, 0x87, 0xF6, 0x65, 0xCC, 0x87, 0xF6, - 0x45, 0xCC, 0xA8, 0xF6, 0x65, 0xCC, 0xA8, 0xF6, - 0x45, 0xCC, 0x8C, 0xF6, 0x65, 0xCC, 0x8C, 0xF6, - 0x47, 0xCC, 0x82, 0xF6, 0x67, 0xCC, 0x82, 0xF6, - 0x47, 0xCC, 0x86, 0xF6, 0x67, 0xCC, 0x86, 0xF6, - 0x47, 0xCC, 0x87, 0xF6, 0x67, 0xCC, 0x87, 0xF6, - 0x47, 0xCC, 0xA7, 0xF6, 0x67, 0xCC, 0xA7, 0xF6, - 0x48, 0xCC, 0x82, 0xF6, 0x68, 0xCC, 0x82, 0xF6, - 0x49, 0xCC, 0x83, 0xF6, 0x69, 0xCC, 0x83, 0xF6, - 0x49, 0xCC, 0x84, 0xF6, 0x69, 0xCC, 0x84, 0xF6, - 0x49, 0xCC, 0x86, 0xF6, 0x69, 0xCC, 0x86, 0xF6, - 0x49, 0xCC, 0xA8, 0xF6, 0x69, 0xCC, 0xA8, 0xF6, - 0x49, 0xCC, 0x87, 0x49, 0x4A, 0x69, 0x6A, 0xF6, - 0x4A, 0xCC, 0x82, 0xF6, 0x6A, 0xCC, 0x82, 0xF6, - 0x4B, 0xCC, 0xA7, 0xF6, 0x6B, 0xCC, 0xA7, 0xF6, - 0x4C, 0xCC, 0x81, 0xF6, 0x6C, 0xCC, 0x81, 0xF6, - 0x4C, 0xCC, 0xA7, 0xF6, 0x6C, 0xCC, 0xA7, 0xF6, - 0x4C, 0xCC, 0x8C, 0xF6, 0x6C, 0xCC, 0x8C, 0x4C, - 0xC2, 0xB7, 0x6C, 0xC2, 0xB7, 0xF6, 0x4E, 0xCC, - 0x81, 0xF6, 0x6E, 0xCC, 0x81, 0xF6, 0x4E, 0xCC, - 0xA7, 0xF6, 0x6E, 0xCC, 0xA7, 0xF6, 0x4E, 0xCC, - 0x8C, 0xF6, 0x6E, 0xCC, 0x8C, 0xCA, 0xBC, 0x6E, - 0xF6, 0x4F, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, 0x84, - 0xF6, 0x4F, 0xCC, 0x86, 0xF6, 0x6F, 0xCC, 0x86, - 0xF6, 0x4F, 0xCC, 0x8B, 0xF6, 0x6F, 0xCC, 0x8B, - 0xF6, 0x52, 0xCC, 0x81, 0xF6, 0x72, 0xCC, 0x81, - 0xF6, 0x52, 0xCC, 0xA7, 0xF6, 0x72, 0xCC, 0xA7, - 0xF6, 0x52, 0xCC, 0x8C, 0xF6, 0x72, 0xCC, 0x8C, - 0xF6, 0x53, 0xCC, 0x81, 0xF6, 0x73, 0xCC, 0x81, - 0xF6, 0x53, 0xCC, 0x82, 0xF6, 0x73, 0xCC, 0x82, - 0xF6, 0x53, 0xCC, 0xA7, 0xF6, 0x73, 0xCC, 0xA7, - 0xF6, 0x53, 0xCC, 0x8C, 0xF6, 0x73, 0xCC, 0x8C, - 0xF6, 0x54, 0xCC, 0xA7, 0xF6, 0x74, 0xCC, 0xA7, - 0xF6, 0x54, 0xCC, 0x8C, 0xF6, 0x74, 0xCC, 0x8C, - 0xF6, 0x55, 0xCC, 0x83, 0xF6, 0x75, 0xCC, 0x83, - 0xF6, 0x55, 0xCC, 0x84, 0xF6, 0x75, 0xCC, 0x84, - 0xF6, 0x55, 0xCC, 0x86, 0xF6, 0x75, 0xCC, 0x86, - 0xF6, 0x55, 0xCC, 0x8A, 0xF6, 0x75, 0xCC, 0x8A, - 0xF6, 0x55, 0xCC, 0x8B, 0xF6, 0x75, 0xCC, 0x8B, - 0xF6, 0x55, 0xCC, 0xA8, 0xF6, 0x75, 0xCC, 0xA8, - 0xF6, 0x57, 0xCC, 0x82, 0xF6, 0x77, 0xCC, 0x82, - 0xF6, 0x59, 0xCC, 0x82, 0xF6, 0x79, 0xCC, 0x82, - 0xF6, 0x59, 0xCC, 0x88, 0xF6, 0x5A, 0xCC, 0x81, - 0xF6, 0x7A, 0xCC, 0x81, 0xF6, 0x5A, 0xCC, 0x87, - 0xF6, 0x7A, 0xCC, 0x87, 0xF6, 0x5A, 0xCC, 0x8C, - 0xF6, 0x7A, 0xCC, 0x8C, 0x73, 0xF6, 0x4F, 0xCC, - 0x9B, 0xF6, 0x6F, 0xCC, 0x9B, 0xF6, 0x55, 0xCC, - 0x9B, 0xF6, 0x75, 0xCC, 0x9B, 0x44, 0x5A, 0xCC, - 0x8C, 0x44, 0x7A, 0xCC, 0x8C, 0x64, 0x7A, 0xCC, - 0x8C, 0x4C, 0x4A, 0x4C, 0x6A, 0x6C, 0x6A, 0x4E, - 0x4A, 0x4E, 0x6A, 0x6E, 0x6A, 0xF6, 0x41, 0xCC, - 0x8C, 0xF6, 0x61, 0xCC, 0x8C, 0xF6, 0x49, 0xCC, - 0x8C, 0xF6, 0x69, 0xCC, 0x8C, 0xF6, 0x4F, 0xCC, - 0x8C, 0xF6, 0x6F, 0xCC, 0x8C, 0xF6, 0x55, 0xCC, - 0x8C, 0xF6, 0x75, 0xCC, 0x8C, 0xF6, 0x55, 0xCC, - 0x88, 0xCC, 0x84, 0xF6, 0x75, 0xCC, 0x88, 0xCC, - 0x84, 0xF6, 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xF6, - 0x75, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0x55, 0xCC, - 0x88, 0xCC, 0x8C, 0xF6, 0x75, 0xCC, 0x88, 0xCC, - 0x8C, 0xF6, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xF6, - 0x75, 0xCC, 0x88, 0xCC, 0x80, 0xF6, 0x41, 0xCC, - 0x88, 0xCC, 0x84, 0xF6, 0x61, 0xCC, 0x88, 0xCC, - 0x84, 0xF6, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xF6, - 0x61, 0xCC, 0x87, 0xCC, 0x84, 0xF6, 0xC3, 0x86, - 0xCC, 0x84, 0xF6, 0xC3, 0xA6, 0xCC, 0x84, 0xF6, - 0x47, 0xCC, 0x8C, 0xF6, 0x67, 0xCC, 0x8C, 0xF6, - 0x4B, 0xCC, 0x8C, 0xF6, 0x6B, 0xCC, 0x8C, 0xF6, - 0x4F, 0xCC, 0xA8, 0xF6, 0x6F, 0xCC, 0xA8, 0xF6, - 0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, - 0xA8, 0xCC, 0x84, 0xF6, 0xC6, 0xB7, 0xCC, 0x8C, - 0xF6, 0xCA, 0x92, 0xCC, 0x8C, 0xF6, 0x6A, 0xCC, - 0x8C, 0x44, 0x5A, 0x44, 0x7A, 0x64, 0x7A, 0xF6, - 0x47, 0xCC, 0x81, 0xF6, 0x67, 0xCC, 0x81, 0xF6, - 0x4E, 0xCC, 0x80, 0xF6, 0x6E, 0xCC, 0x80, 0xF6, - 0x41, 0xCC, 0x8A, 0xCC, 0x81, 0xF6, 0x61, 0xCC, - 0x8A, 0xCC, 0x81, 0xF6, 0xC3, 0x86, 0xCC, 0x81, - 0xF6, 0xC3, 0xA6, 0xCC, 0x81, 0xF6, 0xC3, 0x98, - 0xCC, 0x81, 0xF6, 0xC3, 0xB8, 0xCC, 0x81, 0xF6, - 0x41, 0xCC, 0x8F, 0xF6, 0x61, 0xCC, 0x8F, 0xF6, - 0x41, 0xCC, 0x91, 0xF6, 0x61, 0xCC, 0x91, 0xF6, - 0x45, 0xCC, 0x8F, 0xF6, 0x65, 0xCC, 0x8F, 0xF6, - 0x45, 0xCC, 0x91, 0xF6, 0x65, 0xCC, 0x91, 0xF6, - 0x49, 0xCC, 0x8F, 0xF6, 0x69, 0xCC, 0x8F, 0xF6, - 0x49, 0xCC, 0x91, 0xF6, 0x69, 0xCC, 0x91, 0xF6, - 0x4F, 0xCC, 0x8F, 0xF6, 0x6F, 0xCC, 0x8F, 0xF6, - 0x4F, 0xCC, 0x91, 0xF6, 0x6F, 0xCC, 0x91, 0xF6, - 0x52, 0xCC, 0x8F, 0xF6, 0x72, 0xCC, 0x8F, 0xF6, - 0x52, 0xCC, 0x91, 0xF6, 0x72, 0xCC, 0x91, 0xF6, - 0x55, 0xCC, 0x8F, 0xF6, 0x75, 0xCC, 0x8F, 0xF6, - 0x55, 0xCC, 0x91, 0xF6, 0x75, 0xCC, 0x91, 0xF6, - 0x53, 0xCC, 0xA6, 0xF6, 0x73, 0xCC, 0xA6, 0xF6, - 0x54, 0xCC, 0xA6, 0xF6, 0x74, 0xCC, 0xA6, 0xF6, - 0x48, 0xCC, 0x8C, 0xF6, 0x68, 0xCC, 0x8C, 0xF6, - 0x41, 0xCC, 0x87, 0xF6, 0x61, 0xCC, 0x87, 0xF6, - 0x45, 0xCC, 0xA7, 0xF6, 0x65, 0xCC, 0xA7, 0xF6, - 0x4F, 0xCC, 0x88, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, - 0x88, 0xCC, 0x84, 0xF6, 0x4F, 0xCC, 0x83, 0xCC, - 0x84, 0xF6, 0x6F, 0xCC, 0x83, 0xCC, 0x84, 0xF6, - 0x4F, 0xCC, 0x87, 0xF6, 0x6F, 0xCC, 0x87, 0xF6, - 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, - 0x87, 0xCC, 0x84, 0xF6, 0x59, 0xCC, 0x84, 0xF6, - 0x79, 0xCC, 0x84, 0x68, 0xC9, 0xA6, 0x6A, 0x72, - 0xC9, 0xB9, 0xC9, 0xBB, 0xCA, 0x81, 0x77, 0x79, - 0x20, 0xCC, 0x86, 0x20, 0xCC, 0x87, 0x20, 0xCC, - 0x8A, 0x20, 0xCC, 0xA8, 0x20, 0xCC, 0x83, 0x20, - 0xCC, 0x8B, 0xC9, 0xA3, 0x6C, 0x73, 0x78, 0xCA, - 0x95, 0xF6, 0xCC, 0x80, 0xF6, 0xCC, 0x81, 0xF6, - 0xCC, 0x93, 0xF6, 0xCC, 0x88, 0xCC, 0x81, 0xF6, - 0xCA, 0xB9, 0x20, 0xCD, 0x85, 0xF6, 0x3B, 0x20, - 0xCC, 0x81, 0xF5, 0x05, 0xC2, 0xA8, 0xCC, 0x81, - 0x20, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0xCE, 0x91, - 0xCC, 0x81, 0xF6, 0xC2, 0xB7, 0xF6, 0xCE, 0x95, - 0xCC, 0x81, 0xF6, 0xCE, 0x97, 0xCC, 0x81, 0xF6, - 0xCE, 0x99, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, - 0x81, 0xF6, 0xCE, 0xA5, 0xCC, 0x81, 0xF6, 0xCE, - 0xA9, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x88, - 0xCC, 0x81, 0xF6, 0xCE, 0x99, 0xCC, 0x88, 0xF6, - 0xCE, 0xA5, 0xCC, 0x88, 0xF6, 0xCE, 0xB1, 0xCC, - 0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x81, 0xF6, 0xCE, - 0xB7, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x81, - 0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xF6, - 0xCE, 0xB9, 0xCC, 0x88, 0xF6, 0xCF, 0x85, 0xCC, - 0x88, 0xF6, 0xCE, 0xBF, 0xCC, 0x81, 0xF6, 0xCF, - 0x85, 0xCC, 0x81, 0xF6, 0xCF, 0x89, 0xCC, 0x81, - 0xCE, 0xB2, 0xCE, 0xB8, 0xCE, 0xA5, 0xF5, 0x05, - 0xCF, 0x92, 0xCC, 0x81, 0xCE, 0xA5, 0xCC, 0x81, - 0xF5, 0x05, 0xCF, 0x92, 0xCC, 0x88, 0xCE, 0xA5, - 0xCC, 0x88, 0xCF, 0x86, 0xCF, 0x80, 0xCE, 0xBA, - 0xCF, 0x81, 0xCF, 0x82, 0xCE, 0x98, 0xCE, 0xB5, - 0xF6, 0xD0, 0x95, 0xCC, 0x80, 0xF6, 0xD0, 0x95, - 0xCC, 0x88, 0xF6, 0xD0, 0x93, 0xCC, 0x81, 0xF6, - 0xD0, 0x86, 0xCC, 0x88, 0xF6, 0xD0, 0x9A, 0xCC, - 0x81, 0xF6, 0xD0, 0x98, 0xCC, 0x80, 0xF6, 0xD0, - 0xA3, 0xCC, 0x86, 0xF6, 0xD0, 0x98, 0xCC, 0x86, - 0xF6, 0xD0, 0xB8, 0xCC, 0x86, 0xF6, 0xD0, 0xB5, - 0xCC, 0x80, 0xF6, 0xD0, 0xB5, 0xCC, 0x88, 0xF6, - 0xD0, 0xB3, 0xCC, 0x81, 0xF6, 0xD1, 0x96, 0xCC, - 0x88, 0xF6, 0xD0, 0xBA, 0xCC, 0x81, 0xF6, 0xD0, - 0xB8, 0xCC, 0x80, 0xF6, 0xD1, 0x83, 0xCC, 0x86, - 0xF6, 0xD1, 0xB4, 0xCC, 0x8F, 0xF6, 0xD1, 0xB5, - 0xCC, 0x8F, 0xF6, 0xD0, 0x96, 0xCC, 0x86, 0xF6, - 0xD0, 0xB6, 0xCC, 0x86, 0xF6, 0xD0, 0x90, 0xCC, - 0x86, 0xF6, 0xD0, 0xB0, 0xCC, 0x86, 0xF6, 0xD0, - 0x90, 0xCC, 0x88, 0xF6, 0xD0, 0xB0, 0xCC, 0x88, - 0xF6, 0xD0, 0x95, 0xCC, 0x86, 0xF6, 0xD0, 0xB5, - 0xCC, 0x86, 0xF6, 0xD3, 0x98, 0xCC, 0x88, 0xF6, - 0xD3, 0x99, 0xCC, 0x88, 0xF6, 0xD0, 0x96, 0xCC, - 0x88, 0xF6, 0xD0, 0xB6, 0xCC, 0x88, 0xF6, 0xD0, - 0x97, 0xCC, 0x88, 0xF6, 0xD0, 0xB7, 0xCC, 0x88, - 0xF6, 0xD0, 0x98, 0xCC, 0x84, 0xF6, 0xD0, 0xB8, - 0xCC, 0x84, 0xF6, 0xD0, 0x98, 0xCC, 0x88, 0xF6, - 0xD0, 0xB8, 0xCC, 0x88, 0xF6, 0xD0, 0x9E, 0xCC, - 0x88, 0xF6, 0xD0, 0xBE, 0xCC, 0x88, 0xF6, 0xD3, - 0xA8, 0xCC, 0x88, 0xF6, 0xD3, 0xA9, 0xCC, 0x88, - 0xF6, 0xD0, 0xAD, 0xCC, 0x88, 0xF6, 0xD1, 0x8D, - 0xCC, 0x88, 0xF6, 0xD0, 0xA3, 0xCC, 0x84, 0xF6, - 0xD1, 0x83, 0xCC, 0x84, 0xF6, 0xD0, 0xA3, 0xCC, - 0x88, 0xF6, 0xD1, 0x83, 0xCC, 0x88, 0xF6, 0xD0, - 0xA3, 0xCC, 0x8B, 0xF6, 0xD1, 0x83, 0xCC, 0x8B, - 0xF6, 0xD0, 0xA7, 0xCC, 0x88, 0xF6, 0xD1, 0x87, - 0xCC, 0x88, 0xF6, 0xD0, 0xAB, 0xCC, 0x88, 0xF6, - 0xD1, 0x8B, 0xCC, 0x88, 0xD5, 0xA5, 0xD6, 0x82, - 0xF6, 0xD8, 0xA7, 0xD9, 0x93, 0xF6, 0xD8, 0xA7, - 0xD9, 0x94, 0xF6, 0xD9, 0x88, 0xD9, 0x94, 0xF6, - 0xD8, 0xA7, 0xD9, 0x95, 0xF6, 0xD9, 0x8A, 0xD9, - 0x94, 0xD8, 0xA7, 0xD9, 0xB4, 0xD9, 0x88, 0xD9, - 0xB4, 0xDB, 0x87, 0xD9, 0xB4, 0xD9, 0x8A, 0xD9, - 0xB4, 0xF6, 0xDB, 0x95, 0xD9, 0x94, 0xF6, 0xDB, - 0x81, 0xD9, 0x94, 0xF6, 0xDB, 0x92, 0xD9, 0x94, - 0xF6, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0xF6, - 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, - 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, - 0x95, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0x96, - 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0x97, 0xE0, - 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0x9C, 0xE0, 0xA4, - 0xBC, 0xF6, 0xE0, 0xA4, 0xA1, 0xE0, 0xA4, 0xBC, - 0xF6, 0xE0, 0xA4, 0xA2, 0xE0, 0xA4, 0xBC, 0xF6, - 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, - 0xA4, 0xAF, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA7, - 0x87, 0xE0, 0xA6, 0xBE, 0xF6, 0xE0, 0xA7, 0x87, - 0xE0, 0xA7, 0x97, 0xF6, 0xE0, 0xA6, 0xA1, 0xE0, - 0xA6, 0xBC, 0xF6, 0xE0, 0xA6, 0xA2, 0xE0, 0xA6, - 0xBC, 0xF6, 0xE0, 0xA6, 0xAF, 0xE0, 0xA6, 0xBC, - 0xF6, 0xE0, 0xA8, 0xB2, 0xE0, 0xA8, 0xBC, 0xF6, - 0xE0, 0xA8, 0xB8, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, - 0xA8, 0x96, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xA8, - 0x97, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xA8, 0x9C, - 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xA8, 0xAB, 0xE0, - 0xA8, 0xBC, 0xF6, 0xE0, 0xAD, 0x87, 0xE0, 0xAD, - 0x96, 0xF6, 0xE0, 0xAD, 0x87, 0xE0, 0xAC, 0xBE, - 0xF6, 0xE0, 0xAD, 0x87, 0xE0, 0xAD, 0x97, 0xF6, - 0xE0, 0xAC, 0xA1, 0xE0, 0xAC, 0xBC, 0xF6, 0xE0, - 0xAC, 0xA2, 0xE0, 0xAC, 0xBC, 0xF6, 0xE0, 0xAE, - 0x92, 0xE0, 0xAF, 0x97, 0xF6, 0xE0, 0xAF, 0x86, - 0xE0, 0xAE, 0xBE, 0xF6, 0xE0, 0xAF, 0x87, 0xE0, - 0xAE, 0xBE, 0xF6, 0xE0, 0xAF, 0x86, 0xE0, 0xAF, - 0x97, 0xF6, 0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96, - 0xF6, 0xE0, 0xB2, 0xBF, 0xE0, 0xB3, 0x95, 0xF6, - 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x95, 0xF6, 0xE0, - 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0xF6, 0xE0, 0xB3, - 0x86, 0xE0, 0xB3, 0x82, 0xF6, 0xE0, 0xB3, 0x86, - 0xE0, 0xB3, 0x82, 0xE0, 0xB3, 0x95, 0xF6, 0xE0, - 0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0xF6, 0xE0, 0xB5, - 0x87, 0xE0, 0xB4, 0xBE, 0xF6, 0xE0, 0xB5, 0x86, - 0xE0, 0xB5, 0x97, 0xF6, 0xE0, 0xB7, 0x99, 0xE0, - 0xB7, 0x8A, 0xF6, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, - 0x8F, 0xF6, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8F, - 0xE0, 0xB7, 0x8A, 0xF6, 0xE0, 0xB7, 0x99, 0xE0, - 0xB7, 0x9F, 0xE0, 0xB9, 0x8D, 0xE0, 0xB8, 0xB2, - 0xE0, 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, 0xE0, 0xBA, - 0xAB, 0xE0, 0xBA, 0x99, 0xE0, 0xBA, 0xAB, 0xE0, - 0xBA, 0xA1, 0xE0, 0xBC, 0x8B, 0xF6, 0xE0, 0xBD, - 0x82, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x8C, - 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x91, 0xE0, - 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x96, 0xE0, 0xBE, - 0xB7, 0xF6, 0xE0, 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, - 0xF6, 0xE0, 0xBD, 0x80, 0xE0, 0xBE, 0xB5, 0xF6, - 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB2, 0xF6, 0xE0, - 0xBD, 0xB1, 0xE0, 0xBD, 0xB4, 0xF6, 0xE0, 0xBE, - 0xB2, 0xE0, 0xBE, 0x80, 0xE0, 0xBE, 0xB2, 0xE0, - 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6, 0xE0, 0xBE, - 0xB3, 0xE0, 0xBE, 0x80, 0xE0, 0xBE, 0xB3, 0xE0, - 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6, 0xE0, 0xBD, - 0xB1, 0xE0, 0xBE, 0x80, 0xF6, 0xE0, 0xBE, 0x92, - 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0x9C, 0xE0, - 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0xA1, 0xE0, 0xBE, - 0xB7, 0xF6, 0xE0, 0xBE, 0xA6, 0xE0, 0xBE, 0xB7, - 0xF6, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, 0xB7, 0xF6, - 0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, 0xF6, 0xE1, - 0x80, 0xA5, 0xE1, 0x80, 0xAE, 0xF6, 0x41, 0xCC, - 0xA5, 0xF6, 0x61, 0xCC, 0xA5, 0xF6, 0x42, 0xCC, - 0x87, 0xF6, 0x62, 0xCC, 0x87, 0xF6, 0x42, 0xCC, - 0xA3, 0xF6, 0x62, 0xCC, 0xA3, 0xF6, 0x42, 0xCC, - 0xB1, 0xF6, 0x62, 0xCC, 0xB1, 0xF6, 0x43, 0xCC, - 0xA7, 0xCC, 0x81, 0xF6, 0x63, 0xCC, 0xA7, 0xCC, - 0x81, 0xF6, 0x44, 0xCC, 0x87, 0xF6, 0x64, 0xCC, - 0x87, 0xF6, 0x44, 0xCC, 0xA3, 0xF6, 0x64, 0xCC, - 0xA3, 0xF6, 0x44, 0xCC, 0xB1, 0xF6, 0x64, 0xCC, - 0xB1, 0xF6, 0x44, 0xCC, 0xA7, 0xF6, 0x64, 0xCC, - 0xA7, 0xF6, 0x44, 0xCC, 0xAD, 0xF6, 0x64, 0xCC, - 0xAD, 0xF6, 0x45, 0xCC, 0x84, 0xCC, 0x80, 0xF6, - 0x65, 0xCC, 0x84, 0xCC, 0x80, 0xF6, 0x45, 0xCC, - 0x84, 0xCC, 0x81, 0xF6, 0x65, 0xCC, 0x84, 0xCC, - 0x81, 0xF6, 0x45, 0xCC, 0xAD, 0xF6, 0x65, 0xCC, - 0xAD, 0xF6, 0x45, 0xCC, 0xB0, 0xF6, 0x65, 0xCC, - 0xB0, 0xF6, 0x45, 0xCC, 0xA7, 0xCC, 0x86, 0xF6, - 0x65, 0xCC, 0xA7, 0xCC, 0x86, 0xF6, 0x46, 0xCC, - 0x87, 0xF6, 0x66, 0xCC, 0x87, 0xF6, 0x47, 0xCC, - 0x84, 0xF6, 0x67, 0xCC, 0x84, 0xF6, 0x48, 0xCC, - 0x87, 0xF6, 0x68, 0xCC, 0x87, 0xF6, 0x48, 0xCC, - 0xA3, 0xF6, 0x68, 0xCC, 0xA3, 0xF6, 0x48, 0xCC, - 0x88, 0xF6, 0x68, 0xCC, 0x88, 0xF6, 0x48, 0xCC, - 0xA7, 0xF6, 0x68, 0xCC, 0xA7, 0xF6, 0x48, 0xCC, - 0xAE, 0xF6, 0x68, 0xCC, 0xAE, 0xF6, 0x49, 0xCC, - 0xB0, 0xF6, 0x69, 0xCC, 0xB0, 0xF6, 0x49, 0xCC, - 0x88, 0xCC, 0x81, 0xF6, 0x69, 0xCC, 0x88, 0xCC, - 0x81, 0xF6, 0x4B, 0xCC, 0x81, 0xF6, 0x6B, 0xCC, - 0x81, 0xF6, 0x4B, 0xCC, 0xA3, 0xF6, 0x6B, 0xCC, - 0xA3, 0xF6, 0x4B, 0xCC, 0xB1, 0xF6, 0x6B, 0xCC, - 0xB1, 0xF6, 0x4C, 0xCC, 0xA3, 0xF6, 0x6C, 0xCC, - 0xA3, 0xF6, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, 0xF6, - 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xF6, 0x4C, 0xCC, - 0xB1, 0xF6, 0x6C, 0xCC, 0xB1, 0xF6, 0x4C, 0xCC, - 0xAD, 0xF6, 0x6C, 0xCC, 0xAD, 0xF6, 0x4D, 0xCC, - 0x81, 0xF6, 0x6D, 0xCC, 0x81, 0xF6, 0x4D, 0xCC, - 0x87, 0xF6, 0x6D, 0xCC, 0x87, 0xF6, 0x4D, 0xCC, - 0xA3, 0xF6, 0x6D, 0xCC, 0xA3, 0xF6, 0x4E, 0xCC, - 0x87, 0xF6, 0x6E, 0xCC, 0x87, 0xF6, 0x4E, 0xCC, - 0xA3, 0xF6, 0x6E, 0xCC, 0xA3, 0xF6, 0x4E, 0xCC, - 0xB1, 0xF6, 0x6E, 0xCC, 0xB1, 0xF6, 0x4E, 0xCC, - 0xAD, 0xF6, 0x6E, 0xCC, 0xAD, 0xF6, 0x4F, 0xCC, - 0x83, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x83, 0xCC, - 0x81, 0xF6, 0x4F, 0xCC, 0x83, 0xCC, 0x88, 0xF6, - 0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xF6, 0x4F, 0xCC, - 0x84, 0xCC, 0x80, 0xF6, 0x6F, 0xCC, 0x84, 0xCC, - 0x80, 0xF6, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xF6, - 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xF6, 0x50, 0xCC, - 0x81, 0xF6, 0x70, 0xCC, 0x81, 0xF6, 0x50, 0xCC, - 0x87, 0xF6, 0x70, 0xCC, 0x87, 0xF6, 0x52, 0xCC, - 0x87, 0xF6, 0x72, 0xCC, 0x87, 0xF6, 0x52, 0xCC, - 0xA3, 0xF6, 0x72, 0xCC, 0xA3, 0xF6, 0x52, 0xCC, - 0xA3, 0xCC, 0x84, 0xF6, 0x72, 0xCC, 0xA3, 0xCC, - 0x84, 0xF6, 0x52, 0xCC, 0xB1, 0xF6, 0x72, 0xCC, - 0xB1, 0xF6, 0x53, 0xCC, 0x87, 0xF6, 0x73, 0xCC, - 0x87, 0xF6, 0x53, 0xCC, 0xA3, 0xF6, 0x73, 0xCC, - 0xA3, 0xF6, 0x53, 0xCC, 0x81, 0xCC, 0x87, 0xF6, - 0x73, 0xCC, 0x81, 0xCC, 0x87, 0xF6, 0x53, 0xCC, - 0x8C, 0xCC, 0x87, 0xF6, 0x73, 0xCC, 0x8C, 0xCC, - 0x87, 0xF6, 0x53, 0xCC, 0xA3, 0xCC, 0x87, 0xF6, - 0x73, 0xCC, 0xA3, 0xCC, 0x87, 0xF6, 0x54, 0xCC, - 0x87, 0xF6, 0x74, 0xCC, 0x87, 0xF6, 0x54, 0xCC, - 0xA3, 0xF6, 0x74, 0xCC, 0xA3, 0xF6, 0x54, 0xCC, - 0xB1, 0xF6, 0x74, 0xCC, 0xB1, 0xF6, 0x54, 0xCC, - 0xAD, 0xF6, 0x74, 0xCC, 0xAD, 0xF6, 0x55, 0xCC, - 0xA4, 0xF6, 0x75, 0xCC, 0xA4, 0xF6, 0x55, 0xCC, - 0xB0, 0xF6, 0x75, 0xCC, 0xB0, 0xF6, 0x55, 0xCC, - 0xAD, 0xF6, 0x75, 0xCC, 0xAD, 0xF6, 0x55, 0xCC, - 0x83, 0xCC, 0x81, 0xF6, 0x75, 0xCC, 0x83, 0xCC, - 0x81, 0xF6, 0x55, 0xCC, 0x84, 0xCC, 0x88, 0xF6, - 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xF6, 0x56, 0xCC, - 0x83, 0xF6, 0x76, 0xCC, 0x83, 0xF6, 0x56, 0xCC, - 0xA3, 0xF6, 0x76, 0xCC, 0xA3, 0xF6, 0x57, 0xCC, - 0x80, 0xF6, 0x77, 0xCC, 0x80, 0xF6, 0x57, 0xCC, - 0x81, 0xF6, 0x77, 0xCC, 0x81, 0xF6, 0x57, 0xCC, - 0x88, 0xF6, 0x77, 0xCC, 0x88, 0xF6, 0x57, 0xCC, - 0x87, 0xF6, 0x77, 0xCC, 0x87, 0xF6, 0x57, 0xCC, - 0xA3, 0xF6, 0x77, 0xCC, 0xA3, 0xF6, 0x58, 0xCC, - 0x87, 0xF6, 0x78, 0xCC, 0x87, 0xF6, 0x58, 0xCC, - 0x88, 0xF6, 0x78, 0xCC, 0x88, 0xF6, 0x59, 0xCC, - 0x87, 0xF6, 0x79, 0xCC, 0x87, 0xF6, 0x5A, 0xCC, - 0x82, 0xF6, 0x7A, 0xCC, 0x82, 0xF6, 0x5A, 0xCC, - 0xA3, 0xF6, 0x7A, 0xCC, 0xA3, 0xF6, 0x5A, 0xCC, - 0xB1, 0xF6, 0x7A, 0xCC, 0xB1, 0xF6, 0x68, 0xCC, - 0xB1, 0xF6, 0x74, 0xCC, 0x88, 0xF6, 0x77, 0xCC, - 0x8A, 0xF6, 0x79, 0xCC, 0x8A, 0x61, 0xCA, 0xBE, - 0xF5, 0x05, 0xC5, 0xBF, 0xCC, 0x87, 0x73, 0xCC, - 0x87, 0xF6, 0x41, 0xCC, 0xA3, 0xF6, 0x61, 0xCC, - 0xA3, 0xF6, 0x41, 0xCC, 0x89, 0xF6, 0x61, 0xCC, - 0x89, 0xF6, 0x41, 0xCC, 0x82, 0xCC, 0x81, 0xF6, - 0x61, 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x41, 0xCC, - 0x82, 0xCC, 0x80, 0xF6, 0x61, 0xCC, 0x82, 0xCC, - 0x80, 0xF6, 0x41, 0xCC, 0x82, 0xCC, 0x89, 0xF6, - 0x61, 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x41, 0xCC, - 0x82, 0xCC, 0x83, 0xF6, 0x61, 0xCC, 0x82, 0xCC, - 0x83, 0xF6, 0x41, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, - 0x61, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x41, 0xCC, - 0x86, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x86, 0xCC, - 0x81, 0xF6, 0x41, 0xCC, 0x86, 0xCC, 0x80, 0xF6, - 0x61, 0xCC, 0x86, 0xCC, 0x80, 0xF6, 0x41, 0xCC, - 0x86, 0xCC, 0x89, 0xF6, 0x61, 0xCC, 0x86, 0xCC, - 0x89, 0xF6, 0x41, 0xCC, 0x86, 0xCC, 0x83, 0xF6, - 0x61, 0xCC, 0x86, 0xCC, 0x83, 0xF6, 0x41, 0xCC, - 0xA3, 0xCC, 0x86, 0xF6, 0x61, 0xCC, 0xA3, 0xCC, - 0x86, 0xF6, 0x45, 0xCC, 0xA3, 0xF6, 0x65, 0xCC, - 0xA3, 0xF6, 0x45, 0xCC, 0x89, 0xF6, 0x65, 0xCC, - 0x89, 0xF6, 0x45, 0xCC, 0x83, 0xF6, 0x65, 0xCC, - 0x83, 0xF6, 0x45, 0xCC, 0x82, 0xCC, 0x81, 0xF6, - 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x45, 0xCC, - 0x82, 0xCC, 0x80, 0xF6, 0x65, 0xCC, 0x82, 0xCC, - 0x80, 0xF6, 0x45, 0xCC, 0x82, 0xCC, 0x89, 0xF6, - 0x65, 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x45, 0xCC, - 0x82, 0xCC, 0x83, 0xF6, 0x65, 0xCC, 0x82, 0xCC, - 0x83, 0xF6, 0x45, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, - 0x65, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x49, 0xCC, - 0x89, 0xF6, 0x69, 0xCC, 0x89, 0xF6, 0x49, 0xCC, - 0xA3, 0xF6, 0x69, 0xCC, 0xA3, 0xF6, 0x4F, 0xCC, - 0xA3, 0xF6, 0x6F, 0xCC, 0xA3, 0xF6, 0x4F, 0xCC, - 0x89, 0xF6, 0x6F, 0xCC, 0x89, 0xF6, 0x4F, 0xCC, - 0x82, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x82, 0xCC, - 0x81, 0xF6, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xF6, - 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xF6, 0x4F, 0xCC, - 0x82, 0xCC, 0x89, 0xF6, 0x6F, 0xCC, 0x82, 0xCC, - 0x89, 0xF6, 0x4F, 0xCC, 0x82, 0xCC, 0x83, 0xF6, - 0x6F, 0xCC, 0x82, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, - 0xA3, 0xCC, 0x82, 0xF6, 0x6F, 0xCC, 0xA3, 0xCC, - 0x82, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0x81, 0xF6, - 0x6F, 0xCC, 0x9B, 0xCC, 0x81, 0xF6, 0x4F, 0xCC, - 0x9B, 0xCC, 0x80, 0xF6, 0x6F, 0xCC, 0x9B, 0xCC, - 0x80, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0x89, 0xF6, - 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xF6, 0x4F, 0xCC, - 0x9B, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x9B, 0xCC, - 0x83, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, 0xF6, - 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xF6, 0x55, 0xCC, - 0xA3, 0xF6, 0x75, 0xCC, 0xA3, 0xF6, 0x55, 0xCC, - 0x89, 0xF6, 0x75, 0xCC, 0x89, 0xF6, 0x55, 0xCC, - 0x9B, 0xCC, 0x81, 0xF6, 0x75, 0xCC, 0x9B, 0xCC, - 0x81, 0xF6, 0x55, 0xCC, 0x9B, 0xCC, 0x80, 0xF6, - 0x75, 0xCC, 0x9B, 0xCC, 0x80, 0xF6, 0x55, 0xCC, - 0x9B, 0xCC, 0x89, 0xF6, 0x75, 0xCC, 0x9B, 0xCC, - 0x89, 0xF6, 0x55, 0xCC, 0x9B, 0xCC, 0x83, 0xF6, - 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xF6, 0x55, 0xCC, - 0x9B, 0xCC, 0xA3, 0xF6, 0x75, 0xCC, 0x9B, 0xCC, - 0xA3, 0xF6, 0x59, 0xCC, 0x80, 0xF6, 0x79, 0xCC, - 0x80, 0xF6, 0x59, 0xCC, 0xA3, 0xF6, 0x79, 0xCC, - 0xA3, 0xF6, 0x59, 0xCC, 0x89, 0xF6, 0x79, 0xCC, - 0x89, 0xF6, 0x59, 0xCC, 0x83, 0xF6, 0x79, 0xCC, - 0x83, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xF6, 0xCE, - 0xB1, 0xCC, 0x94, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, - 0xCC, 0x80, 0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, - 0x80, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, 0x81, - 0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xF6, - 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCE, - 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0x91, - 0xCC, 0x93, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xF6, - 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, - 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0x91, - 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCC, - 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCC, 0x93, - 0xCD, 0x82, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCD, - 0x82, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, 0xF6, 0xCE, - 0xB5, 0xCC, 0x94, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, - 0xCC, 0x80, 0xF6, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, - 0x80, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81, - 0xF6, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xF6, - 0xCE, 0x95, 0xCC, 0x93, 0xF6, 0xCE, 0x95, 0xCC, - 0x94, 0xF6, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80, - 0xF6, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xF6, - 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, - 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, - 0xCC, 0x93, 0xF6, 0xCE, 0xB7, 0xCC, 0x94, 0xF6, - 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, - 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xB7, - 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC, - 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC, 0x93, - 0xCD, 0x82, 0xF6, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, - 0x82, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xF6, 0xCE, - 0x97, 0xCC, 0x94, 0xF6, 0xCE, 0x97, 0xCC, 0x93, - 0xCC, 0x80, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, - 0x80, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x81, - 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81, 0xF6, - 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCE, - 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xB9, - 0xCC, 0x93, 0xF6, 0xCE, 0xB9, 0xCC, 0x94, 0xF6, - 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, - 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xB9, - 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, - 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x93, - 0xCD, 0x82, 0xF6, 0xCE, 0xB9, 0xCC, 0x94, 0xCD, - 0x82, 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xF6, 0xCE, - 0x99, 0xCC, 0x94, 0xF6, 0xCE, 0x99, 0xCC, 0x93, - 0xCC, 0x80, 0xF6, 0xCE, 0x99, 0xCC, 0x94, 0xCC, - 0x80, 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81, - 0xF6, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xF6, - 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCE, - 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xBF, - 0xCC, 0x93, 0xF6, 0xCE, 0xBF, 0xCC, 0x94, 0xF6, - 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, - 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xBF, - 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xBF, 0xCC, - 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, 0x93, - 0xF6, 0xCE, 0x9F, 0xCC, 0x94, 0xF6, 0xCE, 0x9F, - 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0x9F, 0xCC, - 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0x9F, 0xCC, 0x93, - 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, 0x94, 0xCC, - 0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xF6, 0xCF, - 0x85, 0xCC, 0x94, 0xF6, 0xCF, 0x85, 0xCC, 0x93, - 0xCC, 0x80, 0xF6, 0xCF, 0x85, 0xCC, 0x94, 0xCC, - 0x80, 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81, - 0xF6, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xF6, - 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCF, - 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xA5, - 0xCC, 0x94, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, - 0x80, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81, - 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xF6, - 0xCF, 0x89, 0xCC, 0x93, 0xF6, 0xCF, 0x89, 0xCC, - 0x94, 0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x80, - 0xF6, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80, 0xF6, - 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCF, - 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCF, 0x89, - 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCF, 0x89, 0xCC, - 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, - 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xF6, 0xCE, 0xA9, - 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC, - 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, - 0xCC, 0x81, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, - 0x81, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x82, - 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82, 0xF6, - 0xCE, 0xB1, 0xCC, 0x80, 0xF6, 0xCE, 0xB1, 0xCC, - 0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x80, 0xF6, 0xCE, - 0xB5, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC, 0x80, - 0xF6, 0xCE, 0xB7, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, - 0xCC, 0x80, 0xF6, 0xCE, 0xB9, 0xCC, 0x81, 0xF6, - 0xCE, 0xBF, 0xCC, 0x80, 0xF6, 0xCE, 0xBF, 0xCC, - 0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x80, 0xF6, 0xCF, - 0x85, 0xCC, 0x81, 0xF6, 0xCF, 0x89, 0xCC, 0x80, - 0xF6, 0xCF, 0x89, 0xCC, 0x81, 0xF6, 0xCE, 0xB1, - 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC, - 0x94, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, - 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC, - 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, - 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE, - 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF6, - 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, - 0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCD, - 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, - 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xF6, - 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, - 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCD, - 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81, - 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCC, - 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, - 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, - 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, - 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, - 0x94, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, 0x93, - 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, - 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, - 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE, - 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF6, - 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, - 0xF6, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82, 0xCD, - 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, - 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xF6, - 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, - 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80, 0xCD, - 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x81, - 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, - 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, - 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, - 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCF, 0x89, - 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC, - 0x94, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC, 0x93, - 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC, - 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89, - 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCF, - 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF6, - 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, - 0xF6, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCD, - 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, - 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xF6, - 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, - 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCD, - 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81, - 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, - 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, - 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, - 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, - 0xCC, 0x86, 0xF6, 0xCE, 0xB1, 0xCC, 0x84, 0xF6, - 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, - 0xB1, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC, 0x81, - 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCD, 0x82, 0xF6, - 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, - 0x91, 0xCC, 0x86, 0xF6, 0xCE, 0x91, 0xCC, 0x84, - 0xF6, 0xCE, 0x91, 0xCC, 0x80, 0xF6, 0xCE, 0x91, - 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCD, 0x85, 0x20, - 0xCC, 0x93, 0xF6, 0xCE, 0xB9, 0x20, 0xCC, 0x93, - 0x20, 0xCD, 0x82, 0xF5, 0x05, 0xC2, 0xA8, 0xCD, - 0x82, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xF6, 0xCE, - 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, - 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, 0x81, 0xCD, - 0x85, 0xF6, 0xCE, 0xB7, 0xCD, 0x82, 0xF6, 0xCE, - 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x95, - 0xCC, 0x80, 0xF6, 0xCE, 0x95, 0xCC, 0x81, 0xF6, - 0xCE, 0x97, 0xCC, 0x80, 0xF6, 0xCE, 0x97, 0xCC, - 0x81, 0xF6, 0xCE, 0x97, 0xCD, 0x85, 0xF5, 0x06, - 0xE1, 0xBE, 0xBF, 0xCC, 0x80, 0x20, 0xCC, 0x93, - 0xCC, 0x80, 0xF5, 0x06, 0xE1, 0xBE, 0xBF, 0xCC, - 0x81, 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xF5, 0x06, - 0xE1, 0xBE, 0xBF, 0xCD, 0x82, 0x20, 0xCC, 0x93, - 0xCD, 0x82, 0xF6, 0xCE, 0xB9, 0xCC, 0x86, 0xF6, - 0xCE, 0xB9, 0xCC, 0x84, 0xF6, 0xCE, 0xB9, 0xCC, - 0x88, 0xCC, 0x80, 0xF6, 0xCE, 0xB9, 0xCC, 0x88, - 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCD, 0x82, 0xF6, - 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xF6, 0xCE, - 0x99, 0xCC, 0x86, 0xF6, 0xCE, 0x99, 0xCC, 0x84, - 0xF6, 0xCE, 0x99, 0xCC, 0x80, 0xF6, 0xCE, 0x99, - 0xCC, 0x81, 0xF5, 0x06, 0xE1, 0xBF, 0xBE, 0xCC, - 0x80, 0x20, 0xCC, 0x94, 0xCC, 0x80, 0xF5, 0x06, - 0xE1, 0xBF, 0xBE, 0xCC, 0x81, 0x20, 0xCC, 0x94, - 0xCC, 0x81, 0xF5, 0x06, 0xE1, 0xBF, 0xBE, 0xCD, - 0x82, 0x20, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCF, - 0x85, 0xCC, 0x86, 0xF6, 0xCF, 0x85, 0xCC, 0x84, - 0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xF6, - 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0xCF, - 0x81, 0xCC, 0x93, 0xF6, 0xCF, 0x81, 0xCC, 0x94, - 0xF6, 0xCF, 0x85, 0xCD, 0x82, 0xF6, 0xCF, 0x85, - 0xCC, 0x88, 0xCD, 0x82, 0xF6, 0xCE, 0xA5, 0xCC, - 0x86, 0xF6, 0xCE, 0xA5, 0xCC, 0x84, 0xF6, 0xCE, - 0xA5, 0xCC, 0x80, 0xF6, 0xCE, 0xA5, 0xCC, 0x81, - 0xF6, 0xCE, 0xA1, 0xCC, 0x94, 0xF5, 0x05, 0xC2, - 0xA8, 0xCC, 0x80, 0x20, 0xCC, 0x88, 0xCC, 0x80, - 0xF5, 0x05, 0xC2, 0xA8, 0xCC, 0x81, 0x20, 0xCC, - 0x88, 0xCC, 0x81, 0xF6, 0x60, 0xF6, 0xCF, 0x89, - 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCD, - 0x85, 0xF6, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85, - 0xF6, 0xCF, 0x89, 0xCD, 0x82, 0xF6, 0xCF, 0x89, - 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x9F, 0xCC, - 0x80, 0xF6, 0xCE, 0x9F, 0xCC, 0x81, 0xF6, 0xCE, - 0xA9, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC, 0x81, - 0xF6, 0xCE, 0xA9, 0xCD, 0x85, 0xF5, 0x03, 0xC2, - 0xB4, 0x20, 0xCC, 0x81, 0x20, 0xCC, 0x94, 0xF5, - 0x04, 0xE2, 0x80, 0x82, 0x20, 0xF5, 0x04, 0xE2, - 0x80, 0x83, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0xE2, 0x80, 0x90, 0x20, - 0xCC, 0xB3, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, - 0x20, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, - 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, - 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, - 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x21, - 0x21, 0x20, 0xCC, 0x85, 0x3F, 0x3F, 0x3F, 0x21, - 0x21, 0x3F, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, - 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x20, 0x30, - 0x69, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, - 0xE2, 0x88, 0x92, 0x3D, 0x28, 0x29, 0x6E, 0x30, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x2B, 0xE2, 0x88, 0x92, 0x3D, 0x28, 0x29, - 0x52, 0x73, 0x61, 0x2F, 0x63, 0x61, 0x2F, 0x73, - 0x43, 0xC2, 0xB0, 0x43, 0x63, 0x2F, 0x6F, 0x63, - 0x2F, 0x75, 0xC6, 0x90, 0xC2, 0xB0, 0x46, 0x67, - 0x48, 0x48, 0x48, 0x68, 0xC4, 0xA7, 0x49, 0x49, - 0x4C, 0x6C, 0x4E, 0x4E, 0x6F, 0x50, 0x51, 0x52, - 0x52, 0x52, 0x53, 0x4D, 0x54, 0x45, 0x4C, 0x54, - 0x4D, 0x5A, 0xF6, 0xCE, 0xA9, 0x5A, 0xF6, 0x4B, - 0xF6, 0x41, 0xCC, 0x8A, 0x42, 0x43, 0x65, 0x45, - 0x46, 0x4D, 0x6F, 0xD7, 0x90, 0xD7, 0x91, 0xD7, - 0x92, 0xD7, 0x93, 0x69, 0xCE, 0xB3, 0xCE, 0x93, - 0xCE, 0xA0, 0xE2, 0x88, 0x91, 0x44, 0x64, 0x65, - 0x69, 0x6A, 0x31, 0xE2, 0x81, 0x84, 0x33, 0x32, - 0xE2, 0x81, 0x84, 0x33, 0x31, 0xE2, 0x81, 0x84, - 0x35, 0x32, 0xE2, 0x81, 0x84, 0x35, 0x33, 0xE2, - 0x81, 0x84, 0x35, 0x34, 0xE2, 0x81, 0x84, 0x35, - 0x31, 0xE2, 0x81, 0x84, 0x36, 0x35, 0xE2, 0x81, - 0x84, 0x36, 0x31, 0xE2, 0x81, 0x84, 0x38, 0x33, - 0xE2, 0x81, 0x84, 0x38, 0x35, 0xE2, 0x81, 0x84, - 0x38, 0x37, 0xE2, 0x81, 0x84, 0x38, 0x31, 0xE2, - 0x81, 0x84, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, - 0x49, 0x56, 0x56, 0x56, 0x49, 0x56, 0x49, 0x49, - 0x56, 0x49, 0x49, 0x49, 0x49, 0x58, 0x58, 0x58, - 0x49, 0x58, 0x49, 0x49, 0x4C, 0x43, 0x44, 0x4D, - 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x76, - 0x76, 0x76, 0x69, 0x76, 0x69, 0x69, 0x76, 0x69, - 0x69, 0x69, 0x69, 0x78, 0x78, 0x78, 0x69, 0x78, - 0x69, 0x69, 0x6C, 0x63, 0x64, 0x6D, 0xF6, 0xE2, - 0x86, 0x90, 0xCC, 0xB8, 0xF6, 0xE2, 0x86, 0x92, - 0xCC, 0xB8, 0xF6, 0xE2, 0x86, 0x94, 0xCC, 0xB8, - 0xF6, 0xE2, 0x87, 0x90, 0xCC, 0xB8, 0xF6, 0xE2, - 0x87, 0x94, 0xCC, 0xB8, 0xF6, 0xE2, 0x87, 0x92, - 0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0x83, 0xCC, 0xB8, - 0xF6, 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0xF6, 0xE2, - 0x88, 0x8B, 0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0xA3, - 0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0xA5, 0xCC, 0xB8, - 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, - 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, - 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, - 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xF6, 0xE2, - 0x88, 0xBC, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0x83, - 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0x85, 0xCC, 0xB8, - 0xF6, 0xE2, 0x89, 0x88, 0xCC, 0xB8, 0xF6, 0x3D, - 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xA1, 0xCC, 0xB8, - 0xF6, 0xE2, 0x89, 0x8D, 0xCC, 0xB8, 0xF6, 0x3C, - 0xCC, 0xB8, 0xF6, 0x3E, 0xCC, 0xB8, 0xF6, 0xE2, - 0x89, 0xA4, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xA5, - 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xB2, 0xCC, 0xB8, - 0xF6, 0xE2, 0x89, 0xB3, 0xCC, 0xB8, 0xF6, 0xE2, - 0x89, 0xB6, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xB7, - 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xBA, 0xCC, 0xB8, - 0xF6, 0xE2, 0x89, 0xBB, 0xCC, 0xB8, 0xF6, 0xE2, - 0x8A, 0x82, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x83, - 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x86, 0xCC, 0xB8, - 0xF6, 0xE2, 0x8A, 0x87, 0xCC, 0xB8, 0xF6, 0xE2, - 0x8A, 0xA2, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xA8, - 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xA9, 0xCC, 0xB8, - 0xF6, 0xE2, 0x8A, 0xAB, 0xCC, 0xB8, 0xF6, 0xE2, - 0x89, 0xBC, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xBD, - 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x91, 0xCC, 0xB8, - 0xF6, 0xE2, 0x8A, 0x92, 0xCC, 0xB8, 0xF6, 0xE2, - 0x8A, 0xB2, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xB3, - 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, - 0xF6, 0xE2, 0x8A, 0xB5, 0xCC, 0xB8, 0xF6, 0xE3, - 0x80, 0x88, 0xF6, 0xE3, 0x80, 0x89, 0x31, 0x32, - 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x31, - 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x31, - 0x34, 0x31, 0x35, 0x31, 0x36, 0x31, 0x37, 0x31, - 0x38, 0x31, 0x39, 0x32, 0x30, 0x28, 0x31, 0x29, - 0x28, 0x32, 0x29, 0x28, 0x33, 0x29, 0x28, 0x34, - 0x29, 0x28, 0x35, 0x29, 0x28, 0x36, 0x29, 0x28, - 0x37, 0x29, 0x28, 0x38, 0x29, 0x28, 0x39, 0x29, - 0x28, 0x31, 0x30, 0x29, 0x28, 0x31, 0x31, 0x29, - 0x28, 0x31, 0x32, 0x29, 0x28, 0x31, 0x33, 0x29, - 0x28, 0x31, 0x34, 0x29, 0x28, 0x31, 0x35, 0x29, - 0x28, 0x31, 0x36, 0x29, 0x28, 0x31, 0x37, 0x29, - 0x28, 0x31, 0x38, 0x29, 0x28, 0x31, 0x39, 0x29, - 0x28, 0x32, 0x30, 0x29, 0x31, 0x2E, 0x32, 0x2E, - 0x33, 0x2E, 0x34, 0x2E, 0x35, 0x2E, 0x36, 0x2E, - 0x37, 0x2E, 0x38, 0x2E, 0x39, 0x2E, 0x31, 0x30, - 0x2E, 0x31, 0x31, 0x2E, 0x31, 0x32, 0x2E, 0x31, - 0x33, 0x2E, 0x31, 0x34, 0x2E, 0x31, 0x35, 0x2E, - 0x31, 0x36, 0x2E, 0x31, 0x37, 0x2E, 0x31, 0x38, - 0x2E, 0x31, 0x39, 0x2E, 0x32, 0x30, 0x2E, 0x28, - 0x61, 0x29, 0x28, 0x62, 0x29, 0x28, 0x63, 0x29, - 0x28, 0x64, 0x29, 0x28, 0x65, 0x29, 0x28, 0x66, - 0x29, 0x28, 0x67, 0x29, 0x28, 0x68, 0x29, 0x28, - 0x69, 0x29, 0x28, 0x6A, 0x29, 0x28, 0x6B, 0x29, - 0x28, 0x6C, 0x29, 0x28, 0x6D, 0x29, 0x28, 0x6E, - 0x29, 0x28, 0x6F, 0x29, 0x28, 0x70, 0x29, 0x28, - 0x71, 0x29, 0x28, 0x72, 0x29, 0x28, 0x73, 0x29, - 0x28, 0x74, 0x29, 0x28, 0x75, 0x29, 0x28, 0x76, - 0x29, 0x28, 0x77, 0x29, 0x28, 0x78, 0x29, 0x28, - 0x79, 0x29, 0x28, 0x7A, 0x29, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x30, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, - 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x3A, 0x3A, - 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0xF6, 0xE2, - 0xAB, 0x9D, 0xCC, 0xB8, 0xE6, 0xAF, 0x8D, 0xE9, - 0xBE, 0x9F, 0xE4, 0xB8, 0x80, 0xE4, 0xB8, 0xA8, - 0xE4, 0xB8, 0xB6, 0xE4, 0xB8, 0xBF, 0xE4, 0xB9, - 0x99, 0xE4, 0xBA, 0x85, 0xE4, 0xBA, 0x8C, 0xE4, - 0xBA, 0xA0, 0xE4, 0xBA, 0xBA, 0xE5, 0x84, 0xBF, - 0xE5, 0x85, 0xA5, 0xE5, 0x85, 0xAB, 0xE5, 0x86, - 0x82, 0xE5, 0x86, 0x96, 0xE5, 0x86, 0xAB, 0xE5, - 0x87, 0xA0, 0xE5, 0x87, 0xB5, 0xE5, 0x88, 0x80, - 0xE5, 0x8A, 0x9B, 0xE5, 0x8B, 0xB9, 0xE5, 0x8C, - 0x95, 0xE5, 0x8C, 0x9A, 0xE5, 0x8C, 0xB8, 0xE5, - 0x8D, 0x81, 0xE5, 0x8D, 0x9C, 0xE5, 0x8D, 0xA9, - 0xE5, 0x8E, 0x82, 0xE5, 0x8E, 0xB6, 0xE5, 0x8F, - 0x88, 0xE5, 0x8F, 0xA3, 0xE5, 0x9B, 0x97, 0xE5, - 0x9C, 0x9F, 0xE5, 0xA3, 0xAB, 0xE5, 0xA4, 0x82, - 0xE5, 0xA4, 0x8A, 0xE5, 0xA4, 0x95, 0xE5, 0xA4, - 0xA7, 0xE5, 0xA5, 0xB3, 0xE5, 0xAD, 0x90, 0xE5, - 0xAE, 0x80, 0xE5, 0xAF, 0xB8, 0xE5, 0xB0, 0x8F, - 0xE5, 0xB0, 0xA2, 0xE5, 0xB0, 0xB8, 0xE5, 0xB1, - 0xAE, 0xE5, 0xB1, 0xB1, 0xE5, 0xB7, 0x9B, 0xE5, - 0xB7, 0xA5, 0xE5, 0xB7, 0xB1, 0xE5, 0xB7, 0xBE, - 0xE5, 0xB9, 0xB2, 0xE5, 0xB9, 0xBA, 0xE5, 0xB9, - 0xBF, 0xE5, 0xBB, 0xB4, 0xE5, 0xBB, 0xBE, 0xE5, - 0xBC, 0x8B, 0xE5, 0xBC, 0x93, 0xE5, 0xBD, 0x90, - 0xE5, 0xBD, 0xA1, 0xE5, 0xBD, 0xB3, 0xE5, 0xBF, - 0x83, 0xE6, 0x88, 0x88, 0xE6, 0x88, 0xB6, 0xE6, - 0x89, 0x8B, 0xE6, 0x94, 0xAF, 0xE6, 0x94, 0xB4, - 0xE6, 0x96, 0x87, 0xE6, 0x96, 0x97, 0xE6, 0x96, - 0xA4, 0xE6, 0x96, 0xB9, 0xE6, 0x97, 0xA0, 0xE6, - 0x97, 0xA5, 0xE6, 0x9B, 0xB0, 0xE6, 0x9C, 0x88, - 0xE6, 0x9C, 0xA8, 0xE6, 0xAC, 0xA0, 0xE6, 0xAD, - 0xA2, 0xE6, 0xAD, 0xB9, 0xE6, 0xAE, 0xB3, 0xE6, - 0xAF, 0x8B, 0xE6, 0xAF, 0x94, 0xE6, 0xAF, 0x9B, - 0xE6, 0xB0, 0x8F, 0xE6, 0xB0, 0x94, 0xE6, 0xB0, - 0xB4, 0xE7, 0x81, 0xAB, 0xE7, 0x88, 0xAA, 0xE7, - 0x88, 0xB6, 0xE7, 0x88, 0xBB, 0xE7, 0x88, 0xBF, - 0xE7, 0x89, 0x87, 0xE7, 0x89, 0x99, 0xE7, 0x89, - 0x9B, 0xE7, 0x8A, 0xAC, 0xE7, 0x8E, 0x84, 0xE7, - 0x8E, 0x89, 0xE7, 0x93, 0x9C, 0xE7, 0x93, 0xA6, - 0xE7, 0x94, 0x98, 0xE7, 0x94, 0x9F, 0xE7, 0x94, - 0xA8, 0xE7, 0x94, 0xB0, 0xE7, 0x96, 0x8B, 0xE7, - 0x96, 0x92, 0xE7, 0x99, 0xB6, 0xE7, 0x99, 0xBD, - 0xE7, 0x9A, 0xAE, 0xE7, 0x9A, 0xBF, 0xE7, 0x9B, - 0xAE, 0xE7, 0x9F, 0x9B, 0xE7, 0x9F, 0xA2, 0xE7, - 0x9F, 0xB3, 0xE7, 0xA4, 0xBA, 0xE7, 0xA6, 0xB8, - 0xE7, 0xA6, 0xBE, 0xE7, 0xA9, 0xB4, 0xE7, 0xAB, - 0x8B, 0xE7, 0xAB, 0xB9, 0xE7, 0xB1, 0xB3, 0xE7, - 0xB3, 0xB8, 0xE7, 0xBC, 0xB6, 0xE7, 0xBD, 0x91, - 0xE7, 0xBE, 0x8A, 0xE7, 0xBE, 0xBD, 0xE8, 0x80, - 0x81, 0xE8, 0x80, 0x8C, 0xE8, 0x80, 0x92, 0xE8, - 0x80, 0xB3, 0xE8, 0x81, 0xBF, 0xE8, 0x82, 0x89, - 0xE8, 0x87, 0xA3, 0xE8, 0x87, 0xAA, 0xE8, 0x87, - 0xB3, 0xE8, 0x87, 0xBC, 0xE8, 0x88, 0x8C, 0xE8, - 0x88, 0x9B, 0xE8, 0x88, 0x9F, 0xE8, 0x89, 0xAE, - 0xE8, 0x89, 0xB2, 0xE8, 0x89, 0xB8, 0xE8, 0x99, - 0x8D, 0xE8, 0x99, 0xAB, 0xE8, 0xA1, 0x80, 0xE8, - 0xA1, 0x8C, 0xE8, 0xA1, 0xA3, 0xE8, 0xA5, 0xBE, - 0xE8, 0xA6, 0x8B, 0xE8, 0xA7, 0x92, 0xE8, 0xA8, - 0x80, 0xE8, 0xB0, 0xB7, 0xE8, 0xB1, 0x86, 0xE8, - 0xB1, 0x95, 0xE8, 0xB1, 0xB8, 0xE8, 0xB2, 0x9D, - 0xE8, 0xB5, 0xA4, 0xE8, 0xB5, 0xB0, 0xE8, 0xB6, - 0xB3, 0xE8, 0xBA, 0xAB, 0xE8, 0xBB, 0x8A, 0xE8, - 0xBE, 0x9B, 0xE8, 0xBE, 0xB0, 0xE8, 0xBE, 0xB5, - 0xE9, 0x82, 0x91, 0xE9, 0x85, 0x89, 0xE9, 0x87, - 0x86, 0xE9, 0x87, 0x8C, 0xE9, 0x87, 0x91, 0xE9, - 0x95, 0xB7, 0xE9, 0x96, 0x80, 0xE9, 0x98, 0x9C, - 0xE9, 0x9A, 0xB6, 0xE9, 0x9A, 0xB9, 0xE9, 0x9B, - 0xA8, 0xE9, 0x9D, 0x91, 0xE9, 0x9D, 0x9E, 0xE9, - 0x9D, 0xA2, 0xE9, 0x9D, 0xA9, 0xE9, 0x9F, 0x8B, - 0xE9, 0x9F, 0xAD, 0xE9, 0x9F, 0xB3, 0xE9, 0xA0, - 0x81, 0xE9, 0xA2, 0xA8, 0xE9, 0xA3, 0x9B, 0xE9, - 0xA3, 0x9F, 0xE9, 0xA6, 0x96, 0xE9, 0xA6, 0x99, - 0xE9, 0xA6, 0xAC, 0xE9, 0xAA, 0xA8, 0xE9, 0xAB, - 0x98, 0xE9, 0xAB, 0x9F, 0xE9, 0xAC, 0xA5, 0xE9, - 0xAC, 0xAF, 0xE9, 0xAC, 0xB2, 0xE9, 0xAC, 0xBC, - 0xE9, 0xAD, 0x9A, 0xE9, 0xB3, 0xA5, 0xE9, 0xB9, - 0xB5, 0xE9, 0xB9, 0xBF, 0xE9, 0xBA, 0xA5, 0xE9, - 0xBA, 0xBB, 0xE9, 0xBB, 0x83, 0xE9, 0xBB, 0x8D, - 0xE9, 0xBB, 0x91, 0xE9, 0xBB, 0xB9, 0xE9, 0xBB, - 0xBD, 0xE9, 0xBC, 0x8E, 0xE9, 0xBC, 0x93, 0xE9, - 0xBC, 0xA0, 0xE9, 0xBC, 0xBB, 0xE9, 0xBD, 0x8A, - 0xE9, 0xBD, 0x92, 0xE9, 0xBE, 0x8D, 0xE9, 0xBE, - 0x9C, 0xE9, 0xBE, 0xA0, 0x20, 0xE3, 0x80, 0x92, - 0xE5, 0x8D, 0x81, 0xE5, 0x8D, 0x84, 0xE5, 0x8D, - 0x85, 0xF6, 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x81, 0x91, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, - 0x93, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x95, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x97, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x99, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x81, 0xA1, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, - 0xA4, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA6, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA8, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xAF, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, - 0xF6, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, - 0x81, 0xB5, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, - 0xB5, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x81, 0xB8, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xB8, 0xE3, - 0x82, 0x9A, 0xF6, 0xE3, 0x81, 0xBB, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, - 0xF6, 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x20, - 0xE3, 0x82, 0x99, 0x20, 0xE3, 0x82, 0x9A, 0xF6, - 0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0xE3, 0x82, - 0x88, 0xE3, 0x82, 0x8A, 0xF6, 0xE3, 0x82, 0xAB, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xAD, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xAF, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x82, 0xB7, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, - 0xB9, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBB, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBD, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBF, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x83, 0x88, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, - 0x8F, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x8F, - 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x83, 0x92, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x92, 0xE3, 0x82, - 0x9A, 0xF6, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0xF6, - 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x83, - 0x9B, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x9B, - 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x82, 0xA6, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x83, 0xAF, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x83, 0xBD, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xB3, - 0xE3, 0x83, 0x88, 0xE1, 0x84, 0x80, 0xE1, 0x84, - 0x81, 0xE1, 0x86, 0xAA, 0xE1, 0x84, 0x82, 0xE1, - 0x86, 0xAC, 0xE1, 0x86, 0xAD, 0xE1, 0x84, 0x83, - 0xE1, 0x84, 0x84, 0xE1, 0x84, 0x85, 0xE1, 0x86, - 0xB0, 0xE1, 0x86, 0xB1, 0xE1, 0x86, 0xB2, 0xE1, - 0x86, 0xB3, 0xE1, 0x86, 0xB4, 0xE1, 0x86, 0xB5, - 0xE1, 0x84, 0x9A, 0xE1, 0x84, 0x86, 0xE1, 0x84, - 0x87, 0xE1, 0x84, 0x88, 0xE1, 0x84, 0xA1, 0xE1, - 0x84, 0x89, 0xE1, 0x84, 0x8A, 0xE1, 0x84, 0x8B, - 0xE1, 0x84, 0x8C, 0xE1, 0x84, 0x8D, 0xE1, 0x84, - 0x8E, 0xE1, 0x84, 0x8F, 0xE1, 0x84, 0x90, 0xE1, - 0x84, 0x91, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, - 0xE1, 0x85, 0xA2, 0xE1, 0x85, 0xA3, 0xE1, 0x85, - 0xA4, 0xE1, 0x85, 0xA5, 0xE1, 0x85, 0xA6, 0xE1, - 0x85, 0xA7, 0xE1, 0x85, 0xA8, 0xE1, 0x85, 0xA9, - 0xE1, 0x85, 0xAA, 0xE1, 0x85, 0xAB, 0xE1, 0x85, - 0xAC, 0xE1, 0x85, 0xAD, 0xE1, 0x85, 0xAE, 0xE1, - 0x85, 0xAF, 0xE1, 0x85, 0xB0, 0xE1, 0x85, 0xB1, - 0xE1, 0x85, 0xB2, 0xE1, 0x85, 0xB3, 0xE1, 0x85, - 0xB4, 0xE1, 0x85, 0xB5, 0xE1, 0x85, 0xA0, 0xE1, - 0x84, 0x94, 0xE1, 0x84, 0x95, 0xE1, 0x87, 0x87, - 0xE1, 0x87, 0x88, 0xE1, 0x87, 0x8C, 0xE1, 0x87, - 0x8E, 0xE1, 0x87, 0x93, 0xE1, 0x87, 0x97, 0xE1, - 0x87, 0x99, 0xE1, 0x84, 0x9C, 0xE1, 0x87, 0x9D, - 0xE1, 0x87, 0x9F, 0xE1, 0x84, 0x9D, 0xE1, 0x84, - 0x9E, 0xE1, 0x84, 0xA0, 0xE1, 0x84, 0xA2, 0xE1, - 0x84, 0xA3, 0xE1, 0x84, 0xA7, 0xE1, 0x84, 0xA9, - 0xE1, 0x84, 0xAB, 0xE1, 0x84, 0xAC, 0xE1, 0x84, - 0xAD, 0xE1, 0x84, 0xAE, 0xE1, 0x84, 0xAF, 0xE1, - 0x84, 0xB2, 0xE1, 0x84, 0xB6, 0xE1, 0x85, 0x80, - 0xE1, 0x85, 0x87, 0xE1, 0x85, 0x8C, 0xE1, 0x87, - 0xB1, 0xE1, 0x87, 0xB2, 0xE1, 0x85, 0x97, 0xE1, - 0x85, 0x98, 0xE1, 0x85, 0x99, 0xE1, 0x86, 0x84, - 0xE1, 0x86, 0x85, 0xE1, 0x86, 0x88, 0xE1, 0x86, - 0x91, 0xE1, 0x86, 0x92, 0xE1, 0x86, 0x94, 0xE1, - 0x86, 0x9E, 0xE1, 0x86, 0xA1, 0xE4, 0xB8, 0x80, - 0xE4, 0xBA, 0x8C, 0xE4, 0xB8, 0x89, 0xE5, 0x9B, - 0x9B, 0xE4, 0xB8, 0x8A, 0xE4, 0xB8, 0xAD, 0xE4, - 0xB8, 0x8B, 0xE7, 0x94, 0xB2, 0xE4, 0xB9, 0x99, - 0xE4, 0xB8, 0x99, 0xE4, 0xB8, 0x81, 0xE5, 0xA4, - 0xA9, 0xE5, 0x9C, 0xB0, 0xE4, 0xBA, 0xBA, 0x28, - 0xE1, 0x84, 0x80, 0x29, 0x28, 0xE1, 0x84, 0x82, - 0x29, 0x28, 0xE1, 0x84, 0x83, 0x29, 0x28, 0xE1, - 0x84, 0x85, 0x29, 0x28, 0xE1, 0x84, 0x86, 0x29, - 0x28, 0xE1, 0x84, 0x87, 0x29, 0x28, 0xE1, 0x84, - 0x89, 0x29, 0x28, 0xE1, 0x84, 0x8B, 0x29, 0x28, - 0xE1, 0x84, 0x8C, 0x29, 0x28, 0xE1, 0x84, 0x8E, - 0x29, 0x28, 0xE1, 0x84, 0x8F, 0x29, 0x28, 0xE1, - 0x84, 0x90, 0x29, 0x28, 0xE1, 0x84, 0x91, 0x29, - 0x28, 0xE1, 0x84, 0x92, 0x29, 0x28, 0xE1, 0x84, - 0x80, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x82, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x83, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x85, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x86, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x87, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x89, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x8B, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x8C, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x8E, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x90, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x91, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x92, 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, - 0x8C, 0xE1, 0x85, 0xAE, 0x29, 0x28, 0xE4, 0xB8, - 0x80, 0x29, 0x28, 0xE4, 0xBA, 0x8C, 0x29, 0x28, - 0xE4, 0xB8, 0x89, 0x29, 0x28, 0xE5, 0x9B, 0x9B, - 0x29, 0x28, 0xE4, 0xBA, 0x94, 0x29, 0x28, 0xE5, - 0x85, 0xAD, 0x29, 0x28, 0xE4, 0xB8, 0x83, 0x29, - 0x28, 0xE5, 0x85, 0xAB, 0x29, 0x28, 0xE4, 0xB9, - 0x9D, 0x29, 0x28, 0xE5, 0x8D, 0x81, 0x29, 0x28, - 0xE6, 0x9C, 0x88, 0x29, 0x28, 0xE7, 0x81, 0xAB, - 0x29, 0x28, 0xE6, 0xB0, 0xB4, 0x29, 0x28, 0xE6, - 0x9C, 0xA8, 0x29, 0x28, 0xE9, 0x87, 0x91, 0x29, - 0x28, 0xE5, 0x9C, 0x9F, 0x29, 0x28, 0xE6, 0x97, - 0xA5, 0x29, 0x28, 0xE6, 0xA0, 0xAA, 0x29, 0x28, - 0xE6, 0x9C, 0x89, 0x29, 0x28, 0xE7, 0xA4, 0xBE, - 0x29, 0x28, 0xE5, 0x90, 0x8D, 0x29, 0x28, 0xE7, - 0x89, 0xB9, 0x29, 0x28, 0xE8, 0xB2, 0xA1, 0x29, - 0x28, 0xE7, 0xA5, 0x9D, 0x29, 0x28, 0xE5, 0x8A, - 0xB4, 0x29, 0x28, 0xE4, 0xBB, 0xA3, 0x29, 0x28, - 0xE5, 0x91, 0xBC, 0x29, 0x28, 0xE5, 0xAD, 0xA6, - 0x29, 0x28, 0xE7, 0x9B, 0xA3, 0x29, 0x28, 0xE4, - 0xBC, 0x81, 0x29, 0x28, 0xE8, 0xB3, 0x87, 0x29, - 0x28, 0xE5, 0x8D, 0x94, 0x29, 0x28, 0xE7, 0xA5, - 0xAD, 0x29, 0x28, 0xE4, 0xBC, 0x91, 0x29, 0x28, - 0xE8, 0x87, 0xAA, 0x29, 0x28, 0xE8, 0x87, 0xB3, - 0x29, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, 0x32, - 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, 0x32, - 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, 0x33, - 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, 0xE1, - 0x84, 0x80, 0xE1, 0x84, 0x82, 0xE1, 0x84, 0x83, - 0xE1, 0x84, 0x85, 0xE1, 0x84, 0x86, 0xE1, 0x84, - 0x87, 0xE1, 0x84, 0x89, 0xE1, 0x84, 0x8B, 0xE1, - 0x84, 0x8C, 0xE1, 0x84, 0x8E, 0xE1, 0x84, 0x8F, - 0xE1, 0x84, 0x90, 0xE1, 0x84, 0x91, 0xE1, 0x84, - 0x92, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0xE1, - 0x84, 0x82, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x83, - 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x85, 0xE1, 0x85, - 0xA1, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0xE1, - 0x84, 0x87, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x89, - 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x8B, 0xE1, 0x85, - 0xA1, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0xE1, - 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x8F, - 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x90, 0xE1, 0x85, - 0xA1, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0xE1, - 0x84, 0x92, 0xE1, 0x85, 0xA1, 0xE4, 0xB8, 0x80, - 0xE4, 0xBA, 0x8C, 0xE4, 0xB8, 0x89, 0xE5, 0x9B, - 0x9B, 0xE4, 0xBA, 0x94, 0xE5, 0x85, 0xAD, 0xE4, - 0xB8, 0x83, 0xE5, 0x85, 0xAB, 0xE4, 0xB9, 0x9D, - 0xE5, 0x8D, 0x81, 0xE6, 0x9C, 0x88, 0xE7, 0x81, - 0xAB, 0xE6, 0xB0, 0xB4, 0xE6, 0x9C, 0xA8, 0xE9, - 0x87, 0x91, 0xE5, 0x9C, 0x9F, 0xE6, 0x97, 0xA5, - 0xE6, 0xA0, 0xAA, 0xE6, 0x9C, 0x89, 0xE7, 0xA4, - 0xBE, 0xE5, 0x90, 0x8D, 0xE7, 0x89, 0xB9, 0xE8, - 0xB2, 0xA1, 0xE7, 0xA5, 0x9D, 0xE5, 0x8A, 0xB4, - 0xE7, 0xA7, 0x98, 0xE7, 0x94, 0xB7, 0xE5, 0xA5, - 0xB3, 0xE9, 0x81, 0xA9, 0xE5, 0x84, 0xAA, 0xE5, - 0x8D, 0xB0, 0xE6, 0xB3, 0xA8, 0xE9, 0xA0, 0x85, - 0xE4, 0xBC, 0x91, 0xE5, 0x86, 0x99, 0xE6, 0xAD, - 0xA3, 0xE4, 0xB8, 0x8A, 0xE4, 0xB8, 0xAD, 0xE4, - 0xB8, 0x8B, 0xE5, 0xB7, 0xA6, 0xE5, 0x8F, 0xB3, - 0xE5, 0x8C, 0xBB, 0xE5, 0xAE, 0x97, 0xE5, 0xAD, - 0xA6, 0xE7, 0x9B, 0xA3, 0xE4, 0xBC, 0x81, 0xE8, - 0xB3, 0x87, 0xE5, 0x8D, 0x94, 0xE5, 0xA4, 0x9C, - 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, - 0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x33, - 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, - 0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x31, 0xE6, - 0x9C, 0x88, 0x32, 0xE6, 0x9C, 0x88, 0x33, 0xE6, - 0x9C, 0x88, 0x34, 0xE6, 0x9C, 0x88, 0x35, 0xE6, - 0x9C, 0x88, 0x36, 0xE6, 0x9C, 0x88, 0x37, 0xE6, - 0x9C, 0x88, 0x38, 0xE6, 0x9C, 0x88, 0x39, 0xE6, - 0x9C, 0x88, 0x31, 0x30, 0xE6, 0x9C, 0x88, 0x31, - 0x31, 0xE6, 0x9C, 0x88, 0x31, 0x32, 0xE6, 0x9C, - 0x88, 0xE3, 0x82, 0xA2, 0xE3, 0x82, 0xA4, 0xE3, - 0x82, 0xA6, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xAA, - 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xAD, 0xE3, 0x82, - 0xAF, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0xB3, 0xE3, - 0x82, 0xB5, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xB9, - 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0xBD, 0xE3, 0x82, - 0xBF, 0xE3, 0x83, 0x81, 0xE3, 0x83, 0x84, 0xE3, - 0x83, 0x86, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x8A, - 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x8C, 0xE3, 0x83, - 0x8D, 0xE3, 0x83, 0x8E, 0xE3, 0x83, 0x8F, 0xE3, - 0x83, 0x92, 0xE3, 0x83, 0x95, 0xE3, 0x83, 0x98, - 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0x9E, 0xE3, 0x83, - 0x9F, 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0xA1, 0xE3, - 0x83, 0xA2, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xA6, - 0xE3, 0x83, 0xA8, 0xE3, 0x83, 0xA9, 0xE3, 0x83, - 0xAA, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xAC, 0xE3, - 0x83, 0xAD, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0xB0, - 0xE3, 0x83, 0xB1, 0xE3, 0x83, 0xB2, 0xE3, 0x82, - 0xA2, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, - 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xA2, - 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3, 0x82, - 0xA1, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3, 0xE3, - 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, - 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xBC, 0xE3, 0x83, - 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x8B, 0xE3, - 0x83, 0xB3, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, - 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0x81, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0xA9, 0xE3, - 0x83, 0xB3, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, - 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, - 0x88, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA8, 0xE3, - 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xBC, - 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, - 0xB9, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xBC, 0xE3, - 0x83, 0xA0, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xA4, - 0xE3, 0x83, 0xAA, 0xE3, 0x82, 0xAB, 0xE3, 0x83, - 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, - 0x82, 0xAB, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAA, - 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0xE3, - 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, - 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xAD, 0xE3, 0x82, - 0x99, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, - 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x8B, - 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAD, 0xE3, 0x83, - 0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0xE3, - 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, - 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0xBC, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, - 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xAF, - 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83, - 0xA0, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, - 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, - 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xAD, 0xE3, 0x83, - 0xAD, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, - 0x83, 0x88, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x82, - 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, - 0x83, 0xA0, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, - 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82, - 0xBB, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA4, 0xE3, - 0x83, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, - 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x8D, 0xE3, 0x82, - 0xB1, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, 0xE3, - 0x82, 0xB3, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x8A, - 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, - 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB5, 0xE3, - 0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, - 0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0x81, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0xE3, - 0x82, 0xB7, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, - 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x82, - 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, - 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, - 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0xBC, 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x86, 0xE3, - 0x82, 0x99, 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0x88, - 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, - 0x88, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x8A, 0xE3, - 0x83, 0x8E, 0xE3, 0x83, 0x8E, 0xE3, 0x83, 0x83, - 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x8F, 0xE3, 0x82, - 0xA4, 0xE3, 0x83, 0x84, 0xE3, 0x83, 0x8F, 0xE3, - 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBB, - 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x83, - 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, - 0x83, 0x84, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAC, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, - 0x82, 0xA2, 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x88, - 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82, - 0x9A, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0xE3, - 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB3, - 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA1, 0xE3, - 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, - 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x95, 0xE3, 0x82, - 0xA3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, - 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x83, - 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xA7, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0x95, 0xE3, 0x83, 0xA9, 0xE3, - 0x83, 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF, - 0xE3, 0x82, 0xBF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, - 0x82, 0xBD, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, - 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x92, 0xE3, 0x83, - 0x98, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x84, 0xE3, - 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, - 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x98, 0xE3, 0x82, - 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB7, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBF, 0xE3, 0x83, - 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA4, 0xE3, - 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x9B, - 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, - 0x88, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xB3, 0xE3, - 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, - 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, - 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xB3, - 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x82, - 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0x9E, 0xE3, - 0x82, 0xA4, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x9E, - 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x8F, 0xE3, 0x83, - 0x9E, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xAF, 0xE3, - 0x83, 0x9E, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7, - 0xE3, 0x83, 0xA7, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0x9F, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, - 0x83, 0xB3, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, - 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, 0xE3, 0x83, - 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, - 0x83, 0xAB, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, - 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA1, 0xE3, 0x82, - 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x88, 0xE3, - 0x83, 0xB3, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC, - 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0xE3, 0x83, - 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, - 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xA6, 0xE3, 0x82, - 0xA2, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0xAA, 0xE3, - 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, - 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xA9, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, - 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xBC, - 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xA0, 0xE3, - 0x83, 0xAC, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, - 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0xB3, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, - 0x83, 0x88, 0x30, 0xE7, 0x82, 0xB9, 0x31, 0xE7, - 0x82, 0xB9, 0x32, 0xE7, 0x82, 0xB9, 0x33, 0xE7, - 0x82, 0xB9, 0x34, 0xE7, 0x82, 0xB9, 0x35, 0xE7, - 0x82, 0xB9, 0x36, 0xE7, 0x82, 0xB9, 0x37, 0xE7, - 0x82, 0xB9, 0x38, 0xE7, 0x82, 0xB9, 0x39, 0xE7, - 0x82, 0xB9, 0x31, 0x30, 0xE7, 0x82, 0xB9, 0x31, - 0x31, 0xE7, 0x82, 0xB9, 0x31, 0x32, 0xE7, 0x82, - 0xB9, 0x31, 0x33, 0xE7, 0x82, 0xB9, 0x31, 0x34, - 0xE7, 0x82, 0xB9, 0x31, 0x35, 0xE7, 0x82, 0xB9, - 0x31, 0x36, 0xE7, 0x82, 0xB9, 0x31, 0x37, 0xE7, - 0x82, 0xB9, 0x31, 0x38, 0xE7, 0x82, 0xB9, 0x31, - 0x39, 0xE7, 0x82, 0xB9, 0x32, 0x30, 0xE7, 0x82, - 0xB9, 0x32, 0x31, 0xE7, 0x82, 0xB9, 0x32, 0x32, - 0xE7, 0x82, 0xB9, 0x32, 0x33, 0xE7, 0x82, 0xB9, - 0x32, 0x34, 0xE7, 0x82, 0xB9, 0x68, 0x50, 0x61, - 0x64, 0x61, 0x41, 0x55, 0x62, 0x61, 0x72, 0x6F, - 0x56, 0x70, 0x63, 0xE5, 0xB9, 0xB3, 0xE6, 0x88, - 0x90, 0xE6, 0x98, 0xAD, 0xE5, 0x92, 0x8C, 0xE5, - 0xA4, 0xA7, 0xE6, 0xAD, 0xA3, 0xE6, 0x98, 0x8E, - 0xE6, 0xB2, 0xBB, 0xE6, 0xA0, 0xAA, 0xE5, 0xBC, - 0x8F, 0xE4, 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x70, - 0x41, 0x6E, 0x41, 0xCE, 0xBC, 0x41, 0x6D, 0x41, - 0x6B, 0x41, 0x4B, 0x42, 0x4D, 0x42, 0x47, 0x42, - 0x63, 0x61, 0x6C, 0x6B, 0x63, 0x61, 0x6C, 0x70, - 0x46, 0x6E, 0x46, 0xCE, 0xBC, 0x46, 0xCE, 0xBC, - 0x67, 0x6D, 0x67, 0x6B, 0x67, 0x48, 0x7A, 0x6B, - 0x48, 0x7A, 0x4D, 0x48, 0x7A, 0x47, 0x48, 0x7A, - 0x54, 0x48, 0x7A, 0xCE, 0xBC, 0x6C, 0x6D, 0x6C, - 0x64, 0x6C, 0x6B, 0x6C, 0x66, 0x6D, 0x6E, 0x6D, - 0xCE, 0xBC, 0x6D, 0x6D, 0x6D, 0x63, 0x6D, 0x6B, - 0x6D, 0x6D, 0x6D, 0x32, 0x63, 0x6D, 0x32, 0x6D, - 0x32, 0x6B, 0x6D, 0x32, 0x6D, 0x6D, 0x33, 0x63, - 0x6D, 0x33, 0x6D, 0x33, 0x6B, 0x6D, 0x33, 0x6D, - 0xE2, 0x88, 0x95, 0x73, 0x6D, 0xE2, 0x88, 0x95, - 0x73, 0x32, 0x50, 0x61, 0x6B, 0x50, 0x61, 0x4D, - 0x50, 0x61, 0x47, 0x50, 0x61, 0x72, 0x61, 0x64, - 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x72, - 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x32, 0x70, - 0x73, 0x6E, 0x73, 0xCE, 0xBC, 0x73, 0x6D, 0x73, - 0x70, 0x56, 0x6E, 0x56, 0xCE, 0xBC, 0x56, 0x6D, - 0x56, 0x6B, 0x56, 0x4D, 0x56, 0x70, 0x57, 0x6E, - 0x57, 0xCE, 0xBC, 0x57, 0x6D, 0x57, 0x6B, 0x57, - 0x4D, 0x57, 0x6B, 0xCE, 0xA9, 0x4D, 0xCE, 0xA9, - 0x61, 0x2E, 0x6D, 0x2E, 0x42, 0x71, 0x63, 0x63, - 0x63, 0x64, 0x43, 0xE2, 0x88, 0x95, 0x6B, 0x67, - 0x43, 0x6F, 0x2E, 0x64, 0x42, 0x47, 0x79, 0x68, - 0x61, 0x48, 0x50, 0x69, 0x6E, 0x4B, 0x4B, 0x4B, - 0x4D, 0x6B, 0x74, 0x6C, 0x6D, 0x6C, 0x6E, 0x6C, - 0x6F, 0x67, 0x6C, 0x78, 0x6D, 0x62, 0x6D, 0x69, - 0x6C, 0x6D, 0x6F, 0x6C, 0x50, 0x48, 0x70, 0x2E, - 0x6D, 0x2E, 0x50, 0x50, 0x4D, 0x50, 0x52, 0x73, - 0x72, 0x53, 0x76, 0x57, 0x62, 0x31, 0xE6, 0x97, - 0xA5, 0x32, 0xE6, 0x97, 0xA5, 0x33, 0xE6, 0x97, - 0xA5, 0x34, 0xE6, 0x97, 0xA5, 0x35, 0xE6, 0x97, - 0xA5, 0x36, 0xE6, 0x97, 0xA5, 0x37, 0xE6, 0x97, - 0xA5, 0x38, 0xE6, 0x97, 0xA5, 0x39, 0xE6, 0x97, - 0xA5, 0x31, 0x30, 0xE6, 0x97, 0xA5, 0x31, 0x31, - 0xE6, 0x97, 0xA5, 0x31, 0x32, 0xE6, 0x97, 0xA5, - 0x31, 0x33, 0xE6, 0x97, 0xA5, 0x31, 0x34, 0xE6, - 0x97, 0xA5, 0x31, 0x35, 0xE6, 0x97, 0xA5, 0x31, - 0x36, 0xE6, 0x97, 0xA5, 0x31, 0x37, 0xE6, 0x97, - 0xA5, 0x31, 0x38, 0xE6, 0x97, 0xA5, 0x31, 0x39, - 0xE6, 0x97, 0xA5, 0x32, 0x30, 0xE6, 0x97, 0xA5, - 0x32, 0x31, 0xE6, 0x97, 0xA5, 0x32, 0x32, 0xE6, - 0x97, 0xA5, 0x32, 0x33, 0xE6, 0x97, 0xA5, 0x32, - 0x34, 0xE6, 0x97, 0xA5, 0x32, 0x35, 0xE6, 0x97, - 0xA5, 0x32, 0x36, 0xE6, 0x97, 0xA5, 0x32, 0x37, - 0xE6, 0x97, 0xA5, 0x32, 0x38, 0xE6, 0x97, 0xA5, - 0x32, 0x39, 0xE6, 0x97, 0xA5, 0x33, 0x30, 0xE6, - 0x97, 0xA5, 0x33, 0x31, 0xE6, 0x97, 0xA5, 0xF6, - 0xE8, 0xB1, 0x88, 0xF6, 0xE6, 0x9B, 0xB4, 0xF6, - 0xE8, 0xBB, 0x8A, 0xF6, 0xE8, 0xB3, 0x88, 0xF6, - 0xE6, 0xBB, 0x91, 0xF6, 0xE4, 0xB8, 0xB2, 0xF6, - 0xE5, 0x8F, 0xA5, 0xF6, 0xE9, 0xBE, 0x9C, 0xF6, - 0xE9, 0xBE, 0x9C, 0xF6, 0xE5, 0xA5, 0x91, 0xF6, - 0xE9, 0x87, 0x91, 0xF6, 0xE5, 0x96, 0x87, 0xF6, - 0xE5, 0xA5, 0x88, 0xF6, 0xE6, 0x87, 0xB6, 0xF6, - 0xE7, 0x99, 0xA9, 0xF6, 0xE7, 0xBE, 0x85, 0xF6, - 0xE8, 0x98, 0xBF, 0xF6, 0xE8, 0x9E, 0xBA, 0xF6, - 0xE8, 0xA3, 0xB8, 0xF6, 0xE9, 0x82, 0x8F, 0xF6, - 0xE6, 0xA8, 0x82, 0xF6, 0xE6, 0xB4, 0x9B, 0xF6, - 0xE7, 0x83, 0x99, 0xF6, 0xE7, 0x8F, 0x9E, 0xF6, - 0xE8, 0x90, 0xBD, 0xF6, 0xE9, 0x85, 0xAA, 0xF6, - 0xE9, 0xA7, 0xB1, 0xF6, 0xE4, 0xBA, 0x82, 0xF6, - 0xE5, 0x8D, 0xB5, 0xF6, 0xE6, 0xAC, 0x84, 0xF6, - 0xE7, 0x88, 0x9B, 0xF6, 0xE8, 0x98, 0xAD, 0xF6, - 0xE9, 0xB8, 0x9E, 0xF6, 0xE5, 0xB5, 0x90, 0xF6, - 0xE6, 0xBF, 0xAB, 0xF6, 0xE8, 0x97, 0x8D, 0xF6, - 0xE8, 0xA5, 0xA4, 0xF6, 0xE6, 0x8B, 0x89, 0xF6, - 0xE8, 0x87, 0x98, 0xF6, 0xE8, 0xA0, 0x9F, 0xF6, - 0xE5, 0xBB, 0x8A, 0xF6, 0xE6, 0x9C, 0x97, 0xF6, - 0xE6, 0xB5, 0xAA, 0xF6, 0xE7, 0x8B, 0xBC, 0xF6, - 0xE9, 0x83, 0x8E, 0xF6, 0xE4, 0xBE, 0x86, 0xF6, - 0xE5, 0x86, 0xB7, 0xF6, 0xE5, 0x8B, 0x9E, 0xF6, - 0xE6, 0x93, 0x84, 0xF6, 0xE6, 0xAB, 0x93, 0xF6, - 0xE7, 0x88, 0x90, 0xF6, 0xE7, 0x9B, 0xA7, 0xF6, - 0xE8, 0x80, 0x81, 0xF6, 0xE8, 0x98, 0x86, 0xF6, - 0xE8, 0x99, 0x9C, 0xF6, 0xE8, 0xB7, 0xAF, 0xF6, - 0xE9, 0x9C, 0xB2, 0xF6, 0xE9, 0xAD, 0xAF, 0xF6, - 0xE9, 0xB7, 0xBA, 0xF6, 0xE7, 0xA2, 0x8C, 0xF6, - 0xE7, 0xA5, 0xBF, 0xF6, 0xE7, 0xB6, 0xA0, 0xF6, - 0xE8, 0x8F, 0x89, 0xF6, 0xE9, 0x8C, 0x84, 0xF6, - 0xE9, 0xB9, 0xBF, 0xF6, 0xE8, 0xAB, 0x96, 0xF6, - 0xE5, 0xA3, 0x9F, 0xF6, 0xE5, 0xBC, 0x84, 0xF6, - 0xE7, 0xB1, 0xA0, 0xF6, 0xE8, 0x81, 0xBE, 0xF6, - 0xE7, 0x89, 0xA2, 0xF6, 0xE7, 0xA3, 0x8A, 0xF6, - 0xE8, 0xB3, 0x82, 0xF6, 0xE9, 0x9B, 0xB7, 0xF6, - 0xE5, 0xA3, 0x98, 0xF6, 0xE5, 0xB1, 0xA2, 0xF6, - 0xE6, 0xA8, 0x93, 0xF6, 0xE6, 0xB7, 0x9A, 0xF6, - 0xE6, 0xBC, 0x8F, 0xF6, 0xE7, 0xB4, 0xAF, 0xF6, - 0xE7, 0xB8, 0xB7, 0xF6, 0xE9, 0x99, 0x8B, 0xF6, - 0xE5, 0x8B, 0x92, 0xF6, 0xE8, 0x82, 0x8B, 0xF6, - 0xE5, 0x87, 0x9C, 0xF6, 0xE5, 0x87, 0x8C, 0xF6, - 0xE7, 0xA8, 0x9C, 0xF6, 0xE7, 0xB6, 0xBE, 0xF6, - 0xE8, 0x8F, 0xB1, 0xF6, 0xE9, 0x99, 0xB5, 0xF6, - 0xE8, 0xAE, 0x80, 0xF6, 0xE6, 0x8B, 0x8F, 0xF6, - 0xE6, 0xA8, 0x82, 0xF6, 0xE8, 0xAB, 0xBE, 0xF6, - 0xE4, 0xB8, 0xB9, 0xF6, 0xE5, 0xAF, 0xA7, 0xF6, - 0xE6, 0x80, 0x92, 0xF6, 0xE7, 0x8E, 0x87, 0xF6, - 0xE7, 0x95, 0xB0, 0xF6, 0xE5, 0x8C, 0x97, 0xF6, - 0xE7, 0xA3, 0xBB, 0xF6, 0xE4, 0xBE, 0xBF, 0xF6, - 0xE5, 0xBE, 0xA9, 0xF6, 0xE4, 0xB8, 0x8D, 0xF6, - 0xE6, 0xB3, 0x8C, 0xF6, 0xE6, 0x95, 0xB8, 0xF6, - 0xE7, 0xB4, 0xA2, 0xF6, 0xE5, 0x8F, 0x83, 0xF6, - 0xE5, 0xA1, 0x9E, 0xF6, 0xE7, 0x9C, 0x81, 0xF6, - 0xE8, 0x91, 0x89, 0xF6, 0xE8, 0xAA, 0xAA, 0xF6, - 0xE6, 0xAE, 0xBA, 0xF6, 0xE8, 0xBE, 0xB0, 0xF6, - 0xE6, 0xB2, 0x88, 0xF6, 0xE6, 0x8B, 0xBE, 0xF6, - 0xE8, 0x8B, 0xA5, 0xF6, 0xE6, 0x8E, 0xA0, 0xF6, - 0xE7, 0x95, 0xA5, 0xF6, 0xE4, 0xBA, 0xAE, 0xF6, - 0xE5, 0x85, 0xA9, 0xF6, 0xE5, 0x87, 0x89, 0xF6, - 0xE6, 0xA2, 0x81, 0xF6, 0xE7, 0xB3, 0xA7, 0xF6, - 0xE8, 0x89, 0xAF, 0xF6, 0xE8, 0xAB, 0x92, 0xF6, - 0xE9, 0x87, 0x8F, 0xF6, 0xE5, 0x8B, 0xB5, 0xF6, - 0xE5, 0x91, 0x82, 0xF6, 0xE5, 0xA5, 0xB3, 0xF6, - 0xE5, 0xBB, 0xAC, 0xF6, 0xE6, 0x97, 0x85, 0xF6, - 0xE6, 0xBF, 0xBE, 0xF6, 0xE7, 0xA4, 0xAA, 0xF6, - 0xE9, 0x96, 0xAD, 0xF6, 0xE9, 0xA9, 0xAA, 0xF6, - 0xE9, 0xBA, 0x97, 0xF6, 0xE9, 0xBB, 0x8E, 0xF6, - 0xE5, 0x8A, 0x9B, 0xF6, 0xE6, 0x9B, 0x86, 0xF6, - 0xE6, 0xAD, 0xB7, 0xF6, 0xE8, 0xBD, 0xA2, 0xF6, - 0xE5, 0xB9, 0xB4, 0xF6, 0xE6, 0x86, 0x90, 0xF6, - 0xE6, 0x88, 0x80, 0xF6, 0xE6, 0x92, 0x9A, 0xF6, - 0xE6, 0xBC, 0xA3, 0xF6, 0xE7, 0x85, 0x89, 0xF6, - 0xE7, 0x92, 0x89, 0xF6, 0xE7, 0xA7, 0x8A, 0xF6, - 0xE7, 0xB7, 0xB4, 0xF6, 0xE8, 0x81, 0xAF, 0xF6, - 0xE8, 0xBC, 0xA6, 0xF6, 0xE8, 0x93, 0xAE, 0xF6, - 0xE9, 0x80, 0xA3, 0xF6, 0xE9, 0x8D, 0x8A, 0xF6, - 0xE5, 0x88, 0x97, 0xF6, 0xE5, 0x8A, 0xA3, 0xF6, - 0xE5, 0x92, 0xBD, 0xF6, 0xE7, 0x83, 0x88, 0xF6, - 0xE8, 0xA3, 0x82, 0xF6, 0xE8, 0xAA, 0xAA, 0xF6, - 0xE5, 0xBB, 0x89, 0xF6, 0xE5, 0xBF, 0xB5, 0xF6, - 0xE6, 0x8D, 0xBB, 0xF6, 0xE6, 0xAE, 0xAE, 0xF6, - 0xE7, 0xB0, 0xBE, 0xF6, 0xE7, 0x8D, 0xB5, 0xF6, - 0xE4, 0xBB, 0xA4, 0xF6, 0xE5, 0x9B, 0xB9, 0xF6, - 0xE5, 0xAF, 0xA7, 0xF6, 0xE5, 0xB6, 0xBA, 0xF6, - 0xE6, 0x80, 0x9C, 0xF6, 0xE7, 0x8E, 0xB2, 0xF6, - 0xE7, 0x91, 0xA9, 0xF6, 0xE7, 0xBE, 0x9A, 0xF6, - 0xE8, 0x81, 0x86, 0xF6, 0xE9, 0x88, 0xB4, 0xF6, - 0xE9, 0x9B, 0xB6, 0xF6, 0xE9, 0x9D, 0x88, 0xF6, - 0xE9, 0xA0, 0x98, 0xF6, 0xE4, 0xBE, 0x8B, 0xF6, - 0xE7, 0xA6, 0xAE, 0xF6, 0xE9, 0x86, 0xB4, 0xF6, - 0xE9, 0x9A, 0xB8, 0xF6, 0xE6, 0x83, 0xA1, 0xF6, - 0xE4, 0xBA, 0x86, 0xF6, 0xE5, 0x83, 0x9A, 0xF6, - 0xE5, 0xAF, 0xAE, 0xF6, 0xE5, 0xB0, 0xBF, 0xF6, - 0xE6, 0x96, 0x99, 0xF6, 0xE6, 0xA8, 0x82, 0xF6, - 0xE7, 0x87, 0x8E, 0xF6, 0xE7, 0x99, 0x82, 0xF6, - 0xE8, 0x93, 0xBC, 0xF6, 0xE9, 0x81, 0xBC, 0xF6, - 0xE9, 0xBE, 0x8D, 0xF6, 0xE6, 0x9A, 0x88, 0xF6, - 0xE9, 0x98, 0xAE, 0xF6, 0xE5, 0x8A, 0x89, 0xF6, - 0xE6, 0x9D, 0xBB, 0xF6, 0xE6, 0x9F, 0xB3, 0xF6, - 0xE6, 0xB5, 0x81, 0xF6, 0xE6, 0xBA, 0x9C, 0xF6, - 0xE7, 0x90, 0x89, 0xF6, 0xE7, 0x95, 0x99, 0xF6, - 0xE7, 0xA1, 0xAB, 0xF6, 0xE7, 0xB4, 0x90, 0xF6, - 0xE9, 0xA1, 0x9E, 0xF6, 0xE5, 0x85, 0xAD, 0xF6, - 0xE6, 0x88, 0xAE, 0xF6, 0xE9, 0x99, 0xB8, 0xF6, - 0xE5, 0x80, 0xAB, 0xF6, 0xE5, 0xB4, 0x99, 0xF6, - 0xE6, 0xB7, 0xAA, 0xF6, 0xE8, 0xBC, 0xAA, 0xF6, - 0xE5, 0xBE, 0x8B, 0xF6, 0xE6, 0x85, 0x84, 0xF6, - 0xE6, 0xA0, 0x97, 0xF6, 0xE7, 0x8E, 0x87, 0xF6, - 0xE9, 0x9A, 0x86, 0xF6, 0xE5, 0x88, 0xA9, 0xF6, - 0xE5, 0x90, 0x8F, 0xF6, 0xE5, 0xB1, 0xA5, 0xF6, - 0xE6, 0x98, 0x93, 0xF6, 0xE6, 0x9D, 0x8E, 0xF6, - 0xE6, 0xA2, 0xA8, 0xF6, 0xE6, 0xB3, 0xA5, 0xF6, - 0xE7, 0x90, 0x86, 0xF6, 0xE7, 0x97, 0xA2, 0xF6, - 0xE7, 0xBD, 0xB9, 0xF6, 0xE8, 0xA3, 0x8F, 0xF6, - 0xE8, 0xA3, 0xA1, 0xF6, 0xE9, 0x87, 0x8C, 0xF6, - 0xE9, 0x9B, 0xA2, 0xF6, 0xE5, 0x8C, 0xBF, 0xF6, - 0xE6, 0xBA, 0xBA, 0xF6, 0xE5, 0x90, 0x9D, 0xF6, - 0xE7, 0x87, 0x90, 0xF6, 0xE7, 0x92, 0x98, 0xF6, - 0xE8, 0x97, 0xBA, 0xF6, 0xE9, 0x9A, 0xA3, 0xF6, - 0xE9, 0xB1, 0x97, 0xF6, 0xE9, 0xBA, 0x9F, 0xF6, - 0xE6, 0x9E, 0x97, 0xF6, 0xE6, 0xB7, 0x8B, 0xF6, - 0xE8, 0x87, 0xA8, 0xF6, 0xE7, 0xAB, 0x8B, 0xF6, - 0xE7, 0xAC, 0xA0, 0xF6, 0xE7, 0xB2, 0x92, 0xF6, - 0xE7, 0x8B, 0x80, 0xF6, 0xE7, 0x82, 0x99, 0xF6, - 0xE8, 0xAD, 0x98, 0xF6, 0xE4, 0xBB, 0x80, 0xF6, - 0xE8, 0x8C, 0xB6, 0xF6, 0xE5, 0x88, 0xBA, 0xF6, - 0xE5, 0x88, 0x87, 0xF6, 0xE5, 0xBA, 0xA6, 0xF6, - 0xE6, 0x8B, 0x93, 0xF6, 0xE7, 0xB3, 0x96, 0xF6, - 0xE5, 0xAE, 0x85, 0xF6, 0xE6, 0xB4, 0x9E, 0xF6, - 0xE6, 0x9A, 0xB4, 0xF6, 0xE8, 0xBC, 0xBB, 0xF6, - 0xE8, 0xA1, 0x8C, 0xF6, 0xE9, 0x99, 0x8D, 0xF6, - 0xE8, 0xA6, 0x8B, 0xF6, 0xE5, 0xBB, 0x93, 0xF6, - 0xE5, 0x85, 0x80, 0xF6, 0xE5, 0x97, 0x80, 0xF6, - 0xE5, 0xA1, 0x9A, 0xF6, 0xE6, 0x99, 0xB4, 0xF6, - 0xE5, 0x87, 0x9E, 0xF6, 0xE7, 0x8C, 0xAA, 0xF6, - 0xE7, 0x9B, 0x8A, 0xF6, 0xE7, 0xA4, 0xBC, 0xF6, - 0xE7, 0xA5, 0x9E, 0xF6, 0xE7, 0xA5, 0xA5, 0xF6, - 0xE7, 0xA6, 0x8F, 0xF6, 0xE9, 0x9D, 0x96, 0xF6, - 0xE7, 0xB2, 0xBE, 0xF6, 0xE7, 0xBE, 0xBD, 0xF6, - 0xE8, 0x98, 0x92, 0xF6, 0xE8, 0xAB, 0xB8, 0xF6, - 0xE9, 0x80, 0xB8, 0xF6, 0xE9, 0x83, 0xBD, 0xF6, - 0xE9, 0xA3, 0xAF, 0xF6, 0xE9, 0xA3, 0xBC, 0xF6, - 0xE9, 0xA4, 0xA8, 0xF6, 0xE9, 0xB6, 0xB4, 0xF6, - 0xE4, 0xBE, 0xAE, 0xF6, 0xE5, 0x83, 0xA7, 0xF6, - 0xE5, 0x85, 0x8D, 0xF6, 0xE5, 0x8B, 0x89, 0xF6, - 0xE5, 0x8B, 0xA4, 0xF6, 0xE5, 0x8D, 0x91, 0xF6, - 0xE5, 0x96, 0x9D, 0xF6, 0xE5, 0x98, 0x86, 0xF6, - 0xE5, 0x99, 0xA8, 0xF6, 0xE5, 0xA1, 0x80, 0xF6, - 0xE5, 0xA2, 0xA8, 0xF6, 0xE5, 0xB1, 0xA4, 0xF6, - 0xE5, 0xB1, 0xAE, 0xF6, 0xE6, 0x82, 0x94, 0xF6, - 0xE6, 0x85, 0xA8, 0xF6, 0xE6, 0x86, 0x8E, 0xF6, - 0xE6, 0x87, 0xB2, 0xF6, 0xE6, 0x95, 0x8F, 0xF6, - 0xE6, 0x97, 0xA2, 0xF6, 0xE6, 0x9A, 0x91, 0xF6, - 0xE6, 0xA2, 0x85, 0xF6, 0xE6, 0xB5, 0xB7, 0xF6, - 0xE6, 0xB8, 0x9A, 0xF6, 0xE6, 0xBC, 0xA2, 0xF6, - 0xE7, 0x85, 0xAE, 0xF6, 0xE7, 0x88, 0xAB, 0xF6, - 0xE7, 0x90, 0xA2, 0xF6, 0xE7, 0xA2, 0x91, 0xF6, - 0xE7, 0xA4, 0xBE, 0xF6, 0xE7, 0xA5, 0x89, 0xF6, - 0xE7, 0xA5, 0x88, 0xF6, 0xE7, 0xA5, 0x90, 0xF6, - 0xE7, 0xA5, 0x96, 0xF6, 0xE7, 0xA5, 0x9D, 0xF6, - 0xE7, 0xA6, 0x8D, 0xF6, 0xE7, 0xA6, 0x8E, 0xF6, - 0xE7, 0xA9, 0x80, 0xF6, 0xE7, 0xAA, 0x81, 0xF6, - 0xE7, 0xAF, 0x80, 0xF6, 0xE7, 0xB7, 0xB4, 0xF6, - 0xE7, 0xB8, 0x89, 0xF6, 0xE7, 0xB9, 0x81, 0xF6, - 0xE7, 0xBD, 0xB2, 0xF6, 0xE8, 0x80, 0x85, 0xF6, - 0xE8, 0x87, 0xAD, 0xF6, 0xE8, 0x89, 0xB9, 0xF6, - 0xE8, 0x89, 0xB9, 0xF6, 0xE8, 0x91, 0x97, 0xF6, - 0xE8, 0xA4, 0x90, 0xF6, 0xE8, 0xA6, 0x96, 0xF6, - 0xE8, 0xAC, 0x81, 0xF6, 0xE8, 0xAC, 0xB9, 0xF6, - 0xE8, 0xB3, 0x93, 0xF6, 0xE8, 0xB4, 0x88, 0xF6, - 0xE8, 0xBE, 0xB6, 0xF6, 0xE9, 0x80, 0xB8, 0xF6, - 0xE9, 0x9B, 0xA3, 0xF6, 0xE9, 0x9F, 0xBF, 0xF6, - 0xE9, 0xA0, 0xBB, 0x66, 0x66, 0x66, 0x69, 0x66, - 0x6C, 0x66, 0x66, 0x69, 0x66, 0x66, 0x6C, 0x73, - 0x74, 0x73, 0x74, 0xD5, 0xB4, 0xD5, 0xB6, 0xD5, - 0xB4, 0xD5, 0xA5, 0xD5, 0xB4, 0xD5, 0xAB, 0xD5, - 0xBE, 0xD5, 0xB6, 0xD5, 0xB4, 0xD5, 0xAD, 0xF6, - 0xD7, 0x99, 0xD6, 0xB4, 0xF6, 0xD7, 0xB2, 0xD6, - 0xB7, 0xD7, 0xA2, 0xD7, 0x90, 0xD7, 0x93, 0xD7, - 0x94, 0xD7, 0x9B, 0xD7, 0x9C, 0xD7, 0x9D, 0xD7, - 0xA8, 0xD7, 0xAA, 0x2B, 0xF6, 0xD7, 0xA9, 0xD7, - 0x81, 0xF6, 0xD7, 0xA9, 0xD7, 0x82, 0xF6, 0xD7, - 0xA9, 0xD6, 0xBC, 0xD7, 0x81, 0xF6, 0xD7, 0xA9, - 0xD6, 0xBC, 0xD7, 0x82, 0xF6, 0xD7, 0x90, 0xD6, - 0xB7, 0xF6, 0xD7, 0x90, 0xD6, 0xB8, 0xF6, 0xD7, - 0x90, 0xD6, 0xBC, 0xF6, 0xD7, 0x91, 0xD6, 0xBC, - 0xF6, 0xD7, 0x92, 0xD6, 0xBC, 0xF6, 0xD7, 0x93, - 0xD6, 0xBC, 0xF6, 0xD7, 0x94, 0xD6, 0xBC, 0xF6, - 0xD7, 0x95, 0xD6, 0xBC, 0xF6, 0xD7, 0x96, 0xD6, - 0xBC, 0xF6, 0xD7, 0x98, 0xD6, 0xBC, 0xF6, 0xD7, - 0x99, 0xD6, 0xBC, 0xF6, 0xD7, 0x9A, 0xD6, 0xBC, - 0xF6, 0xD7, 0x9B, 0xD6, 0xBC, 0xF6, 0xD7, 0x9C, - 0xD6, 0xBC, 0xF6, 0xD7, 0x9E, 0xD6, 0xBC, 0xF6, - 0xD7, 0xA0, 0xD6, 0xBC, 0xF6, 0xD7, 0xA1, 0xD6, - 0xBC, 0xF6, 0xD7, 0xA3, 0xD6, 0xBC, 0xF6, 0xD7, - 0xA4, 0xD6, 0xBC, 0xF6, 0xD7, 0xA6, 0xD6, 0xBC, - 0xF6, 0xD7, 0xA7, 0xD6, 0xBC, 0xF6, 0xD7, 0xA8, - 0xD6, 0xBC, 0xF6, 0xD7, 0xA9, 0xD6, 0xBC, 0xF6, - 0xD7, 0xAA, 0xD6, 0xBC, 0xF6, 0xD7, 0x95, 0xD6, - 0xB9, 0xF6, 0xD7, 0x91, 0xD6, 0xBF, 0xF6, 0xD7, - 0x9B, 0xD6, 0xBF, 0xF6, 0xD7, 0xA4, 0xD6, 0xBF, - 0xD7, 0x90, 0xD7, 0x9C, 0xD9, 0xB1, 0xD9, 0xB1, - 0xD9, 0xBB, 0xD9, 0xBB, 0xD9, 0xBB, 0xD9, 0xBB, - 0xD9, 0xBE, 0xD9, 0xBE, 0xD9, 0xBE, 0xD9, 0xBE, - 0xDA, 0x80, 0xDA, 0x80, 0xDA, 0x80, 0xDA, 0x80, - 0xD9, 0xBA, 0xD9, 0xBA, 0xD9, 0xBA, 0xD9, 0xBA, - 0xD9, 0xBF, 0xD9, 0xBF, 0xD9, 0xBF, 0xD9, 0xBF, - 0xD9, 0xB9, 0xD9, 0xB9, 0xD9, 0xB9, 0xD9, 0xB9, - 0xDA, 0xA4, 0xDA, 0xA4, 0xDA, 0xA4, 0xDA, 0xA4, - 0xDA, 0xA6, 0xDA, 0xA6, 0xDA, 0xA6, 0xDA, 0xA6, - 0xDA, 0x84, 0xDA, 0x84, 0xDA, 0x84, 0xDA, 0x84, - 0xDA, 0x83, 0xDA, 0x83, 0xDA, 0x83, 0xDA, 0x83, - 0xDA, 0x86, 0xDA, 0x86, 0xDA, 0x86, 0xDA, 0x86, - 0xDA, 0x87, 0xDA, 0x87, 0xDA, 0x87, 0xDA, 0x87, - 0xDA, 0x8D, 0xDA, 0x8D, 0xDA, 0x8C, 0xDA, 0x8C, - 0xDA, 0x8E, 0xDA, 0x8E, 0xDA, 0x88, 0xDA, 0x88, - 0xDA, 0x98, 0xDA, 0x98, 0xDA, 0x91, 0xDA, 0x91, - 0xDA, 0xA9, 0xDA, 0xA9, 0xDA, 0xA9, 0xDA, 0xA9, - 0xDA, 0xAF, 0xDA, 0xAF, 0xDA, 0xAF, 0xDA, 0xAF, - 0xDA, 0xB3, 0xDA, 0xB3, 0xDA, 0xB3, 0xDA, 0xB3, - 0xDA, 0xB1, 0xDA, 0xB1, 0xDA, 0xB1, 0xDA, 0xB1, - 0xDA, 0xBA, 0xDA, 0xBA, 0xDA, 0xBB, 0xDA, 0xBB, - 0xDA, 0xBB, 0xDA, 0xBB, 0xDB, 0x95, 0xD9, 0x94, - 0xDB, 0x95, 0xD9, 0x94, 0xDB, 0x81, 0xDB, 0x81, - 0xDB, 0x81, 0xDB, 0x81, 0xDA, 0xBE, 0xDA, 0xBE, - 0xDA, 0xBE, 0xDA, 0xBE, 0xDB, 0x92, 0xDB, 0x92, - 0xDB, 0x92, 0xD9, 0x94, 0xDB, 0x92, 0xD9, 0x94, - 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, - 0xDB, 0x87, 0xDB, 0x87, 0xDB, 0x86, 0xDB, 0x86, - 0xDB, 0x88, 0xDB, 0x88, 0xDB, 0x87, 0xD9, 0xB4, - 0xDB, 0x8B, 0xDB, 0x8B, 0xDB, 0x85, 0xDB, 0x85, - 0xDB, 0x89, 0xDB, 0x89, 0xDB, 0x90, 0xDB, 0x90, - 0xDB, 0x90, 0xDB, 0x90, 0xD9, 0x89, 0xD9, 0x89, - 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x8A, - 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x8A, 0xD9, 0x94, - 0xDB, 0x95, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x95, - 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x8A, 0xD9, 0x94, - 0xDB, 0x87, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x87, - 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0xD9, 0x8A, - 0xD9, 0x94, 0xDB, 0x86, 0xD9, 0x8A, 0xD9, 0x94, - 0xDB, 0x88, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x88, - 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0xD9, 0x8A, - 0xD9, 0x94, 0xDB, 0x90, 0xD9, 0x8A, 0xD9, 0x94, - 0xDB, 0x90, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89, - 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x89, 0xDB, 0x8C, 0xDB, 0x8C, - 0xDB, 0x8C, 0xDB, 0x8C, 0xD9, 0x8A, 0xD9, 0x94, - 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAD, - 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x89, 0xD9, 0x8A, 0xD9, 0x94, - 0xD9, 0x8A, 0xD8, 0xA8, 0xD8, 0xAC, 0xD8, 0xA8, - 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xAE, 0xD8, 0xA8, - 0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x89, 0xD8, 0xA8, - 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD8, 0xAA, - 0xD8, 0xAD, 0xD8, 0xAA, 0xD8, 0xAE, 0xD8, 0xAA, - 0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x89, 0xD8, 0xAA, - 0xD9, 0x8A, 0xD8, 0xAB, 0xD8, 0xAC, 0xD8, 0xAB, - 0xD9, 0x85, 0xD8, 0xAB, 0xD9, 0x89, 0xD8, 0xAB, - 0xD9, 0x8A, 0xD8, 0xAC, 0xD8, 0xAD, 0xD8, 0xAC, - 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, 0xAD, - 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD8, 0xAE, - 0xD8, 0xAD, 0xD8, 0xAE, 0xD9, 0x85, 0xD8, 0xB3, - 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xB3, - 0xD8, 0xAE, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xB5, - 0xD8, 0xAD, 0xD8, 0xB5, 0xD9, 0x85, 0xD8, 0xB6, - 0xD8, 0xAC, 0xD8, 0xB6, 0xD8, 0xAD, 0xD8, 0xB6, - 0xD8, 0xAE, 0xD8, 0xB6, 0xD9, 0x85, 0xD8, 0xB7, - 0xD8, 0xAD, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xB8, - 0xD9, 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD8, 0xB9, - 0xD9, 0x85, 0xD8, 0xBA, 0xD8, 0xAC, 0xD8, 0xBA, - 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAC, 0xD9, 0x81, - 0xD8, 0xAD, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x81, - 0xD9, 0x85, 0xD9, 0x81, 0xD9, 0x89, 0xD9, 0x81, - 0xD9, 0x8A, 0xD9, 0x82, 0xD8, 0xAD, 0xD9, 0x82, - 0xD9, 0x85, 0xD9, 0x82, 0xD9, 0x89, 0xD9, 0x82, - 0xD9, 0x8A, 0xD9, 0x83, 0xD8, 0xA7, 0xD9, 0x83, - 0xD8, 0xAC, 0xD9, 0x83, 0xD8, 0xAD, 0xD9, 0x83, - 0xD8, 0xAE, 0xD9, 0x83, 0xD9, 0x84, 0xD9, 0x83, - 0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x89, 0xD9, 0x83, - 0xD9, 0x8A, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x84, - 0xD8, 0xAD, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x84, - 0xD9, 0x85, 0xD9, 0x84, 0xD9, 0x89, 0xD9, 0x84, - 0xD9, 0x8A, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85, - 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x85, - 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x89, 0xD9, 0x85, - 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x86, - 0xD8, 0xAD, 0xD9, 0x86, 0xD8, 0xAE, 0xD9, 0x86, - 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x89, 0xD9, 0x86, - 0xD9, 0x8A, 0xD9, 0x87, 0xD8, 0xAC, 0xD9, 0x87, - 0xD9, 0x85, 0xD9, 0x87, 0xD9, 0x89, 0xD9, 0x87, - 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xAE, 0xD9, 0x8A, - 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x89, 0xD9, 0x8A, - 0xD9, 0x8A, 0xD8, 0xB0, 0xD9, 0xB0, 0xD8, 0xB1, - 0xD9, 0xB0, 0xD9, 0x89, 0xD9, 0xB0, 0x20, 0xD9, - 0x8C, 0xD9, 0x91, 0x20, 0xD9, 0x8D, 0xD9, 0x91, - 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x20, 0xD9, 0x8F, - 0xD9, 0x91, 0x20, 0xD9, 0x90, 0xD9, 0x91, 0x20, - 0xD9, 0x91, 0xD9, 0xB0, 0xD9, 0x8A, 0xD9, 0x94, - 0xD8, 0xB1, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xB2, - 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x86, 0xD9, 0x8A, 0xD9, 0x94, - 0xD9, 0x89, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x8A, - 0xD8, 0xA8, 0xD8, 0xB1, 0xD8, 0xA8, 0xD8, 0xB2, - 0xD8, 0xA8, 0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x86, - 0xD8, 0xA8, 0xD9, 0x89, 0xD8, 0xA8, 0xD9, 0x8A, - 0xD8, 0xAA, 0xD8, 0xB1, 0xD8, 0xAA, 0xD8, 0xB2, - 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x86, - 0xD8, 0xAA, 0xD9, 0x89, 0xD8, 0xAA, 0xD9, 0x8A, - 0xD8, 0xAB, 0xD8, 0xB1, 0xD8, 0xAB, 0xD8, 0xB2, - 0xD8, 0xAB, 0xD9, 0x85, 0xD8, 0xAB, 0xD9, 0x86, - 0xD8, 0xAB, 0xD9, 0x89, 0xD8, 0xAB, 0xD9, 0x8A, - 0xD9, 0x81, 0xD9, 0x89, 0xD9, 0x81, 0xD9, 0x8A, - 0xD9, 0x82, 0xD9, 0x89, 0xD9, 0x82, 0xD9, 0x8A, - 0xD9, 0x83, 0xD8, 0xA7, 0xD9, 0x83, 0xD9, 0x84, - 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x89, - 0xD9, 0x83, 0xD9, 0x8A, 0xD9, 0x84, 0xD9, 0x85, - 0xD9, 0x84, 0xD9, 0x89, 0xD9, 0x84, 0xD9, 0x8A, - 0xD9, 0x85, 0xD8, 0xA7, 0xD9, 0x85, 0xD9, 0x85, - 0xD9, 0x86, 0xD8, 0xB1, 0xD9, 0x86, 0xD8, 0xB2, - 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x86, - 0xD9, 0x86, 0xD9, 0x89, 0xD9, 0x86, 0xD9, 0x8A, - 0xD9, 0x89, 0xD9, 0xB0, 0xD9, 0x8A, 0xD8, 0xB1, - 0xD9, 0x8A, 0xD8, 0xB2, 0xD9, 0x8A, 0xD9, 0x85, - 0xD9, 0x8A, 0xD9, 0x86, 0xD9, 0x8A, 0xD9, 0x89, - 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x94, - 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAD, - 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x94, - 0xD9, 0x87, 0xD8, 0xA8, 0xD8, 0xAC, 0xD8, 0xA8, - 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xAE, 0xD8, 0xA8, - 0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x87, 0xD8, 0xAA, - 0xD8, 0xAC, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAA, - 0xD8, 0xAE, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAA, - 0xD9, 0x87, 0xD8, 0xAB, 0xD9, 0x85, 0xD8, 0xAC, - 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD, - 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, - 0xD8, 0xAC, 0xD8, 0xAE, 0xD9, 0x85, 0xD8, 0xB3, - 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xB3, - 0xD8, 0xAE, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xB5, - 0xD8, 0xAD, 0xD8, 0xB5, 0xD8, 0xAE, 0xD8, 0xB5, - 0xD9, 0x85, 0xD8, 0xB6, 0xD8, 0xAC, 0xD8, 0xB6, - 0xD8, 0xAD, 0xD8, 0xB6, 0xD8, 0xAE, 0xD8, 0xB6, - 0xD9, 0x85, 0xD8, 0xB7, 0xD8, 0xAD, 0xD8, 0xB8, - 0xD9, 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD8, 0xB9, - 0xD9, 0x85, 0xD8, 0xBA, 0xD8, 0xAC, 0xD8, 0xBA, - 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAC, 0xD9, 0x81, - 0xD8, 0xAD, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x81, - 0xD9, 0x85, 0xD9, 0x82, 0xD8, 0xAD, 0xD9, 0x82, - 0xD9, 0x85, 0xD9, 0x83, 0xD8, 0xAC, 0xD9, 0x83, - 0xD8, 0xAD, 0xD9, 0x83, 0xD8, 0xAE, 0xD9, 0x83, - 0xD9, 0x84, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x84, - 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x84, - 0xD8, 0xAE, 0xD9, 0x84, 0xD9, 0x85, 0xD9, 0x84, - 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85, - 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x85, - 0xD9, 0x85, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x86, - 0xD8, 0xAD, 0xD9, 0x86, 0xD8, 0xAE, 0xD9, 0x86, - 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x87, 0xD9, 0x87, - 0xD8, 0xAC, 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x87, - 0xD9, 0xB0, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xAE, 0xD9, 0x8A, - 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x87, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x94, - 0xD9, 0x87, 0xD8, 0xA8, 0xD9, 0x85, 0xD8, 0xA8, - 0xD9, 0x87, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAA, - 0xD9, 0x87, 0xD8, 0xAB, 0xD9, 0x85, 0xD8, 0xAB, - 0xD9, 0x87, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xB3, - 0xD9, 0x87, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xB4, - 0xD9, 0x87, 0xD9, 0x83, 0xD9, 0x84, 0xD9, 0x83, - 0xD9, 0x85, 0xD9, 0x84, 0xD9, 0x85, 0xD9, 0x86, - 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x87, 0xD9, 0x8A, - 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x87, 0xD9, 0x80, - 0xD9, 0x8E, 0xD9, 0x91, 0xD9, 0x80, 0xD9, 0x8F, - 0xD9, 0x91, 0xD9, 0x80, 0xD9, 0x90, 0xD9, 0x91, - 0xD8, 0xB7, 0xD9, 0x89, 0xD8, 0xB7, 0xD9, 0x8A, - 0xD8, 0xB9, 0xD9, 0x89, 0xD8, 0xB9, 0xD9, 0x8A, - 0xD8, 0xBA, 0xD9, 0x89, 0xD8, 0xBA, 0xD9, 0x8A, - 0xD8, 0xB3, 0xD9, 0x89, 0xD8, 0xB3, 0xD9, 0x8A, - 0xD8, 0xB4, 0xD9, 0x89, 0xD8, 0xB4, 0xD9, 0x8A, - 0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xAD, 0xD9, 0x8A, - 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xAE, 0xD9, 0x8A, - 0xD8, 0xB5, 0xD9, 0x89, 0xD8, 0xB5, 0xD9, 0x8A, - 0xD8, 0xB6, 0xD9, 0x89, 0xD8, 0xB6, 0xD9, 0x8A, - 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, 0xAD, - 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, 0x85, - 0xD8, 0xB4, 0xD8, 0xB1, 0xD8, 0xB3, 0xD8, 0xB1, - 0xD8, 0xB5, 0xD8, 0xB1, 0xD8, 0xB6, 0xD8, 0xB1, - 0xD8, 0xB7, 0xD9, 0x89, 0xD8, 0xB7, 0xD9, 0x8A, - 0xD8, 0xB9, 0xD9, 0x89, 0xD8, 0xB9, 0xD9, 0x8A, - 0xD8, 0xBA, 0xD9, 0x89, 0xD8, 0xBA, 0xD9, 0x8A, - 0xD8, 0xB3, 0xD9, 0x89, 0xD8, 0xB3, 0xD9, 0x8A, - 0xD8, 0xB4, 0xD9, 0x89, 0xD8, 0xB4, 0xD9, 0x8A, - 0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xAD, 0xD9, 0x8A, - 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xAE, 0xD9, 0x8A, - 0xD8, 0xB5, 0xD9, 0x89, 0xD8, 0xB5, 0xD9, 0x8A, - 0xD8, 0xB6, 0xD9, 0x89, 0xD8, 0xB6, 0xD9, 0x8A, - 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, 0xAD, - 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, 0x85, - 0xD8, 0xB4, 0xD8, 0xB1, 0xD8, 0xB3, 0xD8, 0xB1, - 0xD8, 0xB5, 0xD8, 0xB1, 0xD8, 0xB6, 0xD8, 0xB1, - 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, 0xAD, - 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, 0x85, - 0xD8, 0xB3, 0xD9, 0x87, 0xD8, 0xB4, 0xD9, 0x87, - 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xB3, 0xD8, 0xAC, - 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xB3, 0xD8, 0xAE, - 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, 0xAD, - 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB7, 0xD9, 0x85, - 0xD8, 0xB8, 0xD9, 0x85, 0xD8, 0xA7, 0xD9, 0x8B, - 0xD8, 0xA7, 0xD9, 0x8B, 0xD8, 0xAA, 0xD8, 0xAC, - 0xD9, 0x85, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, - 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, 0xAA, - 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAA, 0xD8, 0xAE, - 0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC, - 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAA, - 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD9, 0x85, - 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD, - 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xAD, - 0xD9, 0x85, 0xD9, 0x89, 0xD8, 0xB3, 0xD8, 0xAD, - 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAC, 0xD8, 0xAD, - 0xD8, 0xB3, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xB3, - 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xB3, 0xD9, 0x85, - 0xD8, 0xAD, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAC, - 0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB3, - 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB5, 0xD8, 0xAD, - 0xD8, 0xAD, 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, 0xAD, - 0xD8, 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB4, - 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xB4, 0xD8, 0xAD, - 0xD9, 0x85, 0xD8, 0xB4, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xB4, - 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, 0x85, - 0xD9, 0x85, 0xD8, 0xB4, 0xD9, 0x85, 0xD9, 0x85, - 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xB6, - 0xD8, 0xAE, 0xD9, 0x85, 0xD8, 0xB6, 0xD8, 0xAE, - 0xD9, 0x85, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, - 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xB7, - 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB7, 0xD9, 0x85, - 0xD9, 0x8A, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85, - 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB9, - 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB9, 0xD9, 0x85, - 0xD9, 0x89, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x85, - 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xBA, - 0xD9, 0x85, 0xD9, 0x89, 0xD9, 0x81, 0xD8, 0xAE, - 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x85, - 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x82, - 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x84, 0xD8, 0xAD, - 0xD9, 0x85, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x8A, - 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, 0xD9, 0x84, - 0xD8, 0xAC, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAC, - 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, - 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0xD9, 0x84, - 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x84, 0xD9, 0x85, - 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, - 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x85, - 0xD8, 0xAD, 0xD9, 0x8A, 0xD9, 0x85, 0xD8, 0xAC, - 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85, - 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD9, 0x85, - 0xD8, 0xAE, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xAC, - 0xD8, 0xAE, 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC, - 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x86, - 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x86, 0xD8, 0xAD, - 0xD9, 0x89, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, - 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x86, - 0xD8, 0xAC, 0xD9, 0x89, 0xD9, 0x86, 0xD9, 0x85, - 0xD9, 0x8A, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x89, - 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x8A, - 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xA8, 0xD8, 0xAE, - 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAA, - 0xD8, 0xAE, 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAE, - 0xD9, 0x89, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x8A, - 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0xD8, 0xAC, - 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xAC, 0xD8, 0xAD, - 0xD9, 0x89, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89, - 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xB5, - 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xB4, 0xD8, 0xAD, - 0xD9, 0x8A, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, - 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x84, - 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAD, - 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x85, - 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x82, 0xD9, 0x85, - 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x8A, - 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x84, - 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xB9, 0xD9, 0x85, - 0xD9, 0x8A, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x8A, - 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x85, - 0xD8, 0xAE, 0xD9, 0x8A, 0xD9, 0x84, 0xD8, 0xAC, - 0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85, - 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x86, - 0xD8, 0xAC, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, 0xAD, - 0xD9, 0x8A, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x81, - 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xA8, 0xD8, 0xAD, - 0xD9, 0x8A, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85, - 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xB5, - 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB3, 0xD8, 0xAE, - 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x8A, - 0xD8, 0xB5, 0xD9, 0x84, 0xDB, 0x92, 0xD9, 0x82, - 0xD9, 0x84, 0xDB, 0x92, 0xD8, 0xA7, 0xD9, 0x84, - 0xD9, 0x84, 0xD9, 0x87, 0xD8, 0xA7, 0xD9, 0x83, - 0xD8, 0xA8, 0xD8, 0xB1, 0xD9, 0x85, 0xD8, 0xAD, - 0xD9, 0x85, 0xD8, 0xAF, 0xD8, 0xB5, 0xD9, 0x84, - 0xD8, 0xB9, 0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xB3, - 0xD9, 0x88, 0xD9, 0x84, 0xD8, 0xB9, 0xD9, 0x84, - 0xD9, 0x8A, 0xD9, 0x87, 0xD9, 0x88, 0xD8, 0xB3, - 0xD9, 0x84, 0xD9, 0x85, 0xD8, 0xB5, 0xD9, 0x84, - 0xD9, 0x89, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89, - 0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9, - 0x87, 0x20, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A, - 0xD9, 0x87, 0x20, 0xD9, 0x88, 0xD8, 0xB3, 0xD9, - 0x84, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x84, 0x20, - 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x84, - 0xD9, 0x87, 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, - 0xD9, 0x84, 0x2E, 0x2E, 0xE2, 0x80, 0x94, 0xE2, - 0x80, 0x93, 0x5F, 0x5F, 0x28, 0x29, 0x7B, 0x7D, - 0xE3, 0x80, 0x94, 0xE3, 0x80, 0x95, 0xE3, 0x80, - 0x90, 0xE3, 0x80, 0x91, 0xE3, 0x80, 0x8A, 0xE3, - 0x80, 0x8B, 0xE3, 0x80, 0x88, 0xE3, 0x80, 0x89, - 0xE3, 0x80, 0x8C, 0xE3, 0x80, 0x8D, 0xE3, 0x80, - 0x8E, 0xE3, 0x80, 0x8F, 0x20, 0xCC, 0x85, 0x20, - 0xCC, 0x85, 0x20, 0xCC, 0x85, 0x20, 0xCC, 0x85, - 0x5F, 0x5F, 0x5F, 0x2C, 0xE3, 0x80, 0x81, 0x2E, - 0x3B, 0x3A, 0x3F, 0x21, 0xE2, 0x80, 0x94, 0x28, - 0x29, 0x7B, 0x7D, 0xE3, 0x80, 0x94, 0xE3, 0x80, - 0x95, 0x23, 0x26, 0x2A, 0x2B, 0x2D, 0x3C, 0x3E, - 0x3D, 0x5C, 0x24, 0x25, 0x40, 0x20, 0xD9, 0x8B, - 0xD9, 0x80, 0xD9, 0x8B, 0x20, 0xD9, 0x8C, 0x20, - 0xD9, 0x8D, 0x20, 0xD9, 0x8E, 0xD9, 0x80, 0xD9, - 0x8E, 0x20, 0xD9, 0x8F, 0xD9, 0x80, 0xD9, 0x8F, - 0x20, 0xD9, 0x90, 0xD9, 0x80, 0xD9, 0x90, 0x20, - 0xD9, 0x91, 0xD9, 0x80, 0xD9, 0x91, 0x20, 0xD9, - 0x92, 0xD9, 0x80, 0xD9, 0x92, 0xD8, 0xA1, 0xD8, - 0xA7, 0xD9, 0x93, 0xD8, 0xA7, 0xD9, 0x93, 0xD8, - 0xA7, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x94, 0xD9, - 0x88, 0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x94, 0xD8, - 0xA7, 0xD9, 0x95, 0xD8, 0xA7, 0xD9, 0x95, 0xD9, - 0x8A, 0xD9, 0x94, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, - 0x8A, 0xD9, 0x94, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, - 0xA7, 0xD8, 0xA7, 0xD8, 0xA8, 0xD8, 0xA8, 0xD8, - 0xA8, 0xD8, 0xA8, 0xD8, 0xA9, 0xD8, 0xA9, 0xD8, - 0xAA, 0xD8, 0xAA, 0xD8, 0xAA, 0xD8, 0xAA, 0xD8, - 0xAB, 0xD8, 0xAB, 0xD8, 0xAB, 0xD8, 0xAB, 0xD8, - 0xAC, 0xD8, 0xAC, 0xD8, 0xAC, 0xD8, 0xAC, 0xD8, - 0xAD, 0xD8, 0xAD, 0xD8, 0xAD, 0xD8, 0xAD, 0xD8, - 0xAE, 0xD8, 0xAE, 0xD8, 0xAE, 0xD8, 0xAE, 0xD8, - 0xAF, 0xD8, 0xAF, 0xD8, 0xB0, 0xD8, 0xB0, 0xD8, - 0xB1, 0xD8, 0xB1, 0xD8, 0xB2, 0xD8, 0xB2, 0xD8, - 0xB3, 0xD8, 0xB3, 0xD8, 0xB3, 0xD8, 0xB3, 0xD8, - 0xB4, 0xD8, 0xB4, 0xD8, 0xB4, 0xD8, 0xB4, 0xD8, - 0xB5, 0xD8, 0xB5, 0xD8, 0xB5, 0xD8, 0xB5, 0xD8, - 0xB6, 0xD8, 0xB6, 0xD8, 0xB6, 0xD8, 0xB6, 0xD8, - 0xB7, 0xD8, 0xB7, 0xD8, 0xB7, 0xD8, 0xB7, 0xD8, - 0xB8, 0xD8, 0xB8, 0xD8, 0xB8, 0xD8, 0xB8, 0xD8, - 0xB9, 0xD8, 0xB9, 0xD8, 0xB9, 0xD8, 0xB9, 0xD8, - 0xBA, 0xD8, 0xBA, 0xD8, 0xBA, 0xD8, 0xBA, 0xD9, - 0x81, 0xD9, 0x81, 0xD9, 0x81, 0xD9, 0x81, 0xD9, - 0x82, 0xD9, 0x82, 0xD9, 0x82, 0xD9, 0x82, 0xD9, - 0x83, 0xD9, 0x83, 0xD9, 0x83, 0xD9, 0x83, 0xD9, - 0x84, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x84, 0xD9, - 0x85, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x85, 0xD9, - 0x86, 0xD9, 0x86, 0xD9, 0x86, 0xD9, 0x86, 0xD9, - 0x87, 0xD9, 0x87, 0xD9, 0x87, 0xD9, 0x87, 0xD9, - 0x88, 0xD9, 0x88, 0xD9, 0x89, 0xD9, 0x89, 0xD9, - 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, - 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xD9, 0x84, 0xD8, - 0xA7, 0xD9, 0x93, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, - 0x94, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xD9, - 0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xD9, 0x84, 0xD8, - 0xA7, 0xD9, 0x95, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, - 0x84, 0xD8, 0xA7, 0x21, 0x22, 0x23, 0x24, 0x25, - 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, - 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, - 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, - 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, - 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, - 0x7E, 0xE2, 0xA6, 0x85, 0xE2, 0xA6, 0x86, 0xE3, - 0x80, 0x82, 0xE3, 0x80, 0x8C, 0xE3, 0x80, 0x8D, - 0xE3, 0x80, 0x81, 0xE3, 0x83, 0xBB, 0xE3, 0x83, - 0xB2, 0xE3, 0x82, 0xA1, 0xE3, 0x82, 0xA3, 0xE3, - 0x82, 0xA5, 0xE3, 0x82, 0xA7, 0xE3, 0x82, 0xA9, - 0xE3, 0x83, 0xA3, 0xE3, 0x83, 0xA5, 0xE3, 0x83, - 0xA7, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0xBC, 0xE3, - 0x82, 0xA2, 0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xA6, - 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xAA, 0xE3, 0x82, - 0xAB, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, - 0x82, 0xB1, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB5, - 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xB9, 0xE3, 0x82, - 0xBB, 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0xBF, 0xE3, - 0x83, 0x81, 0xE3, 0x83, 0x84, 0xE3, 0x83, 0x86, - 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x8A, 0xE3, 0x83, - 0x8B, 0xE3, 0x83, 0x8C, 0xE3, 0x83, 0x8D, 0xE3, - 0x83, 0x8E, 0xE3, 0x83, 0x8F, 0xE3, 0x83, 0x92, - 0xE3, 0x83, 0x95, 0xE3, 0x83, 0x98, 0xE3, 0x83, - 0x9B, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x9F, 0xE3, - 0x83, 0xA0, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xA2, - 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xA6, 0xE3, 0x83, - 0xA8, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xAA, 0xE3, - 0x83, 0xAB, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAD, - 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0xB3, 0xE3, 0x82, - 0x99, 0xE3, 0x82, 0x9A, 0xE1, 0x85, 0xA0, 0xE1, - 0x84, 0x80, 0xE1, 0x84, 0x81, 0xE1, 0x86, 0xAA, - 0xE1, 0x84, 0x82, 0xE1, 0x86, 0xAC, 0xE1, 0x86, - 0xAD, 0xE1, 0x84, 0x83, 0xE1, 0x84, 0x84, 0xE1, - 0x84, 0x85, 0xE1, 0x86, 0xB0, 0xE1, 0x86, 0xB1, - 0xE1, 0x86, 0xB2, 0xE1, 0x86, 0xB3, 0xE1, 0x86, - 0xB4, 0xE1, 0x86, 0xB5, 0xE1, 0x84, 0x9A, 0xE1, - 0x84, 0x86, 0xE1, 0x84, 0x87, 0xE1, 0x84, 0x88, - 0xE1, 0x84, 0xA1, 0xE1, 0x84, 0x89, 0xE1, 0x84, - 0x8A, 0xE1, 0x84, 0x8B, 0xE1, 0x84, 0x8C, 0xE1, - 0x84, 0x8D, 0xE1, 0x84, 0x8E, 0xE1, 0x84, 0x8F, - 0xE1, 0x84, 0x90, 0xE1, 0x84, 0x91, 0xE1, 0x84, - 0x92, 0xE1, 0x85, 0xA1, 0xE1, 0x85, 0xA2, 0xE1, - 0x85, 0xA3, 0xE1, 0x85, 0xA4, 0xE1, 0x85, 0xA5, - 0xE1, 0x85, 0xA6, 0xE1, 0x85, 0xA7, 0xE1, 0x85, - 0xA8, 0xE1, 0x85, 0xA9, 0xE1, 0x85, 0xAA, 0xE1, - 0x85, 0xAB, 0xE1, 0x85, 0xAC, 0xE1, 0x85, 0xAD, - 0xE1, 0x85, 0xAE, 0xE1, 0x85, 0xAF, 0xE1, 0x85, - 0xB0, 0xE1, 0x85, 0xB1, 0xE1, 0x85, 0xB2, 0xE1, - 0x85, 0xB3, 0xE1, 0x85, 0xB4, 0xE1, 0x85, 0xB5, - 0xC2, 0xA2, 0xC2, 0xA3, 0xC2, 0xAC, 0x20, 0xCC, - 0x84, 0xC2, 0xA6, 0xC2, 0xA5, 0xE2, 0x82, 0xA9, - 0xE2, 0x94, 0x82, 0xE2, 0x86, 0x90, 0xE2, 0x86, - 0x91, 0xE2, 0x86, 0x92, 0xE2, 0x86, 0x93, 0xE2, - 0x96, 0xA0, 0xE2, 0x97, 0x8B, 0xF6, 0xF0, 0x9D, - 0x85, 0x97, 0xF0, 0x9D, 0x85, 0xA5, 0xF6, 0xF0, - 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF6, - 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, - 0xF0, 0x9D, 0x85, 0xAE, 0xF6, 0xF0, 0x9D, 0x85, - 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, - 0xAF, 0xF6, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, - 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0xF6, 0xF0, - 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, - 0x9D, 0x85, 0xB1, 0xF6, 0xF0, 0x9D, 0x85, 0x98, - 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, - 0xF6, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, - 0xA5, 0xF6, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, - 0x85, 0xA5, 0xF6, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, - 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xF6, - 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, - 0xF0, 0x9D, 0x85, 0xAE, 0xF6, 0xF0, 0x9D, 0x86, - 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, - 0xAF, 0xF6, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, - 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x41, 0x42, - 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, - 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, - 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, - 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, - 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, - 0x65, 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x43, 0x44, 0x47, 0x4A, 0x4B, 0x4E, - 0x4F, 0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x66, - 0x68, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x44, - 0x45, 0x46, 0x47, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, - 0x4F, 0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, - 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x44, 0x45, - 0x46, 0x47, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4F, - 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE, - 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE, - 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE, - 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE, - 0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE, - 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE, - 0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1, - 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5, - 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9, - 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD, - 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81, - 0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, - 0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, - 0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, - 0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF, 0x80, 0xCE, - 0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE, - 0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE, - 0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, - 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, - 0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, - 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, - 0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2, - 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, - 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, - 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, - 0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82, - 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86, - 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88, - 0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF, - 0x86, 0xCF, 0x81, 0xCF, 0x80, 0xCE, 0x91, 0xCE, - 0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, - 0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, - 0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, - 0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, - 0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, - 0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2, - 0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, - 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7, - 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB, - 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF, - 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83, - 0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, - 0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE, - 0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF, - 0x81, 0xCF, 0x80, 0xCE, 0x91, 0xCE, 0x92, 0xCE, - 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, - 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, - 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, - 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE, - 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, - 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87, - 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, - 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, - 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, - 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, - 0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84, - 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88, - 0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE, - 0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF, - 0x80, 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE, - 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE, - 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE, - 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE, - 0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE, - 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE, - 0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1, - 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5, - 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9, - 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD, - 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81, - 0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, - 0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, - 0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, - 0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF, 0x80, 0x30, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, - 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0xF6, 0xE4, 0xB8, 0xBD, 0xF6, 0xE4, 0xB8, - 0xB8, 0xF6, 0xE4, 0xB9, 0x81, 0xF6, 0xF0, 0xA0, - 0x84, 0xA2, 0xF6, 0xE4, 0xBD, 0xA0, 0xF6, 0xE4, - 0xBE, 0xAE, 0xF6, 0xE4, 0xBE, 0xBB, 0xF6, 0xE5, - 0x80, 0x82, 0xF6, 0xE5, 0x81, 0xBA, 0xF6, 0xE5, - 0x82, 0x99, 0xF6, 0xE5, 0x83, 0xA7, 0xF6, 0xE5, - 0x83, 0x8F, 0xF6, 0xE3, 0x92, 0x9E, 0xF6, 0xF0, - 0xA0, 0x98, 0xBA, 0xF6, 0xE5, 0x85, 0x8D, 0xF6, - 0xE5, 0x85, 0x94, 0xF6, 0xE5, 0x85, 0xA4, 0xF6, - 0xE5, 0x85, 0xB7, 0xF6, 0xF0, 0xA0, 0x94, 0x9C, - 0xF6, 0xE3, 0x92, 0xB9, 0xF6, 0xE5, 0x85, 0xA7, - 0xF6, 0xE5, 0x86, 0x8D, 0xF6, 0xF0, 0xA0, 0x95, - 0x8B, 0xF6, 0xE5, 0x86, 0x97, 0xF6, 0xE5, 0x86, - 0xA4, 0xF6, 0xE4, 0xBB, 0x8C, 0xF6, 0xE5, 0x86, - 0xAC, 0xF6, 0xE5, 0x86, 0xB5, 0xF6, 0xF0, 0xA9, - 0x87, 0x9F, 0xF6, 0xE5, 0x87, 0xB5, 0xF6, 0xE5, - 0x88, 0x83, 0xF6, 0xE3, 0x93, 0x9F, 0xF6, 0xE5, - 0x88, 0xBB, 0xF6, 0xE5, 0x89, 0x86, 0xF6, 0xE5, - 0x89, 0xB2, 0xF6, 0xE5, 0x89, 0xB7, 0xF6, 0xE3, - 0x94, 0x95, 0xF6, 0xE5, 0x8B, 0x87, 0xF6, 0xE5, - 0x8B, 0x89, 0xF6, 0xE5, 0x8B, 0xA4, 0xF6, 0xE5, - 0x8B, 0xBA, 0xF6, 0xE5, 0x8C, 0x85, 0xF6, 0xE5, - 0x8C, 0x86, 0xF6, 0xE5, 0x8C, 0x97, 0xF6, 0xE5, - 0x8D, 0x89, 0xF6, 0xE5, 0x8D, 0x91, 0xF6, 0xE5, - 0x8D, 0x9A, 0xF6, 0xE5, 0x8D, 0xB3, 0xF6, 0xE5, - 0x8D, 0xBD, 0xF6, 0xE5, 0x8D, 0xBF, 0xF6, 0xE5, - 0x8D, 0xBF, 0xF6, 0xE5, 0x8D, 0xBF, 0xF6, 0xF0, - 0xA0, 0xA8, 0xAC, 0xF6, 0xE7, 0x81, 0xB0, 0xF6, - 0xE5, 0x8F, 0x8A, 0xF6, 0xE5, 0x8F, 0x9F, 0xF6, - 0xF0, 0xA0, 0xAD, 0xA3, 0xF6, 0xE5, 0x8F, 0xAB, - 0xF6, 0xE5, 0x8F, 0xB1, 0xF6, 0xE5, 0x90, 0x86, - 0xF6, 0xE5, 0x92, 0x9E, 0xF6, 0xE5, 0x90, 0xB8, - 0xF6, 0xE5, 0x91, 0x88, 0xF6, 0xE5, 0x91, 0xA8, - 0xF6, 0xE5, 0x92, 0xA2, 0xF6, 0xE5, 0x93, 0xB6, - 0xF6, 0xE5, 0x94, 0x90, 0xF6, 0xE5, 0x95, 0x93, - 0xF6, 0xE5, 0x95, 0xA3, 0xF6, 0xE5, 0x96, 0x84, - 0xF6, 0xE5, 0x96, 0x84, 0xF6, 0xE5, 0x96, 0x99, - 0xF6, 0xE5, 0x96, 0xAB, 0xF6, 0xE5, 0x96, 0xB3, - 0xF6, 0xE5, 0x97, 0x82, 0xF6, 0xE5, 0x9C, 0x96, - 0xF6, 0xE5, 0x98, 0x86, 0xF6, 0xE5, 0x9C, 0x97, - 0xF6, 0xE5, 0x99, 0x91, 0xF6, 0xE5, 0x99, 0xB4, - 0xF6, 0xE5, 0x88, 0x87, 0xF6, 0xE5, 0xA3, 0xAE, - 0xF6, 0xE5, 0x9F, 0x8E, 0xF6, 0xE5, 0x9F, 0xB4, - 0xF6, 0xE5, 0xA0, 0x8D, 0xF6, 0xE5, 0x9E, 0x8B, - 0xF6, 0xE5, 0xA0, 0xB2, 0xF6, 0xE5, 0xA0, 0xB1, - 0xF6, 0xE5, 0xA2, 0xAC, 0xF6, 0xF0, 0xA1, 0x93, - 0xA4, 0xF6, 0xE5, 0xA3, 0xB2, 0xF6, 0xE5, 0xA3, - 0xB7, 0xF6, 0xE5, 0xA4, 0x86, 0xF6, 0xE5, 0xA4, - 0x9A, 0xF6, 0xE5, 0xA4, 0xA2, 0xF6, 0xE5, 0xA5, - 0xA2, 0xF6, 0xF0, 0xA1, 0x9A, 0xA8, 0xF6, 0xF0, - 0xA1, 0x9B, 0xAA, 0xF6, 0xE5, 0xA7, 0xAC, 0xF6, - 0xE5, 0xA8, 0x9B, 0xF6, 0xE5, 0xA8, 0xA7, 0xF6, - 0xE5, 0xA7, 0x98, 0xF6, 0xE5, 0xA9, 0xA6, 0xF6, - 0xE3, 0x9B, 0xAE, 0xF6, 0xE3, 0x9B, 0xBC, 0xF6, - 0xE5, 0xAC, 0x88, 0xF6, 0xE5, 0xAC, 0xBE, 0xF6, - 0xE5, 0xAC, 0xBE, 0xF6, 0xF0, 0xA1, 0xA7, 0x88, - 0xF6, 0xE5, 0xAF, 0x83, 0xF6, 0xE5, 0xAF, 0x98, - 0xF6, 0xE5, 0xAF, 0xA7, 0xF6, 0xE5, 0xAF, 0xB3, - 0xF6, 0xF0, 0xA1, 0xAC, 0x98, 0xF6, 0xE5, 0xAF, - 0xBF, 0xF6, 0xE5, 0xB0, 0x86, 0xF6, 0xE5, 0xBD, - 0x93, 0xF6, 0xE5, 0xB0, 0xA2, 0xF6, 0xE3, 0x9E, - 0x81, 0xF6, 0xE5, 0xB1, 0xA0, 0xF6, 0xE5, 0xB1, - 0xAE, 0xF6, 0xE5, 0xB3, 0x80, 0xF6, 0xE5, 0xB2, - 0x8D, 0xF6, 0xF0, 0xA1, 0xB7, 0xA4, 0xF6, 0xE5, - 0xB5, 0x83, 0xF6, 0xF0, 0xA1, 0xB7, 0xA6, 0xF6, - 0xE5, 0xB5, 0xAE, 0xF6, 0xE5, 0xB5, 0xAB, 0xF6, - 0xE5, 0xB5, 0xBC, 0xF6, 0xE5, 0xB7, 0xA1, 0xF6, - 0xE5, 0xB7, 0xA2, 0xF6, 0xE3, 0xA0, 0xAF, 0xF6, - 0xE5, 0xB7, 0xBD, 0xF6, 0xE5, 0xB8, 0xA8, 0xF6, - 0xE5, 0xB8, 0xBD, 0xF6, 0xE5, 0xB9, 0xA9, 0xF6, - 0xE3, 0xA1, 0xA2, 0xF6, 0xF0, 0xA2, 0x86, 0x83, - 0xF6, 0xE3, 0xA1, 0xBC, 0xF6, 0xE5, 0xBA, 0xB0, - 0xF6, 0xE5, 0xBA, 0xB3, 0xF6, 0xE5, 0xBA, 0xB6, - 0xF6, 0xE5, 0xBB, 0x8A, 0xF6, 0xF0, 0xAA, 0x8E, - 0x92, 0xF6, 0xE5, 0xBB, 0xBE, 0xF6, 0xF0, 0xA2, - 0x8C, 0xB1, 0xF6, 0xF0, 0xA2, 0x8C, 0xB1, 0xF6, - 0xE8, 0x88, 0x81, 0xF6, 0xE5, 0xBC, 0xA2, 0xF6, - 0xE5, 0xBC, 0xA2, 0xF6, 0xE3, 0xA3, 0x87, 0xF6, - 0xF0, 0xA3, 0x8A, 0xB8, 0xF6, 0xF0, 0xA6, 0x87, - 0x9A, 0xF6, 0xE5, 0xBD, 0xA2, 0xF6, 0xE5, 0xBD, - 0xAB, 0xF6, 0xE3, 0xA3, 0xA3, 0xF6, 0xE5, 0xBE, - 0x9A, 0xF6, 0xE5, 0xBF, 0x8D, 0xF6, 0xE5, 0xBF, - 0x97, 0xF6, 0xE5, 0xBF, 0xB9, 0xF6, 0xE6, 0x82, - 0x81, 0xF6, 0xE3, 0xA4, 0xBA, 0xF6, 0xE3, 0xA4, - 0x9C, 0xF6, 0xE6, 0x82, 0x94, 0xF6, 0xF0, 0xA2, - 0x9B, 0x94, 0xF6, 0xE6, 0x83, 0x87, 0xF6, 0xE6, - 0x85, 0x88, 0xF6, 0xE6, 0x85, 0x8C, 0xF6, 0xE6, - 0x85, 0x8E, 0xF6, 0xE6, 0x85, 0x8C, 0xF6, 0xE6, - 0x85, 0xBA, 0xF6, 0xE6, 0x86, 0x8E, 0xF6, 0xE6, - 0x86, 0xB2, 0xF6, 0xE6, 0x86, 0xA4, 0xF6, 0xE6, - 0x86, 0xAF, 0xF6, 0xE6, 0x87, 0x9E, 0xF6, 0xE6, - 0x87, 0xB2, 0xF6, 0xE6, 0x87, 0xB6, 0xF6, 0xE6, - 0x88, 0x90, 0xF6, 0xE6, 0x88, 0x9B, 0xF6, 0xE6, - 0x89, 0x9D, 0xF6, 0xE6, 0x8A, 0xB1, 0xF6, 0xE6, - 0x8B, 0x94, 0xF6, 0xE6, 0x8D, 0x90, 0xF6, 0xF0, - 0xA2, 0xAC, 0x8C, 0xF6, 0xE6, 0x8C, 0xBD, 0xF6, - 0xE6, 0x8B, 0xBC, 0xF6, 0xE6, 0x8D, 0xA8, 0xF6, - 0xE6, 0x8E, 0x83, 0xF6, 0xE6, 0x8F, 0xA4, 0xF6, - 0xF0, 0xA2, 0xAF, 0xB1, 0xF6, 0xE6, 0x90, 0xA2, - 0xF6, 0xE6, 0x8F, 0x85, 0xF6, 0xE6, 0x8E, 0xA9, - 0xF6, 0xE3, 0xA8, 0xAE, 0xF6, 0xE6, 0x91, 0xA9, - 0xF6, 0xE6, 0x91, 0xBE, 0xF6, 0xE6, 0x92, 0x9D, - 0xF6, 0xE6, 0x91, 0xB7, 0xF6, 0xE3, 0xA9, 0xAC, - 0xF6, 0xE6, 0x95, 0x8F, 0xF6, 0xE6, 0x95, 0xAC, - 0xF6, 0xF0, 0xA3, 0x80, 0x8A, 0xF6, 0xE6, 0x97, - 0xA3, 0xF6, 0xE6, 0x9B, 0xB8, 0xF6, 0xE6, 0x99, - 0x89, 0xF6, 0xE3, 0xAC, 0x99, 0xF6, 0xE6, 0x9A, - 0x91, 0xF6, 0xE3, 0xAC, 0x88, 0xF6, 0xE3, 0xAB, - 0xA4, 0xF6, 0xE5, 0x86, 0x92, 0xF6, 0xE5, 0x86, - 0x95, 0xF6, 0xE6, 0x9C, 0x80, 0xF6, 0xE6, 0x9A, - 0x9C, 0xF6, 0xE8, 0x82, 0xAD, 0xF6, 0xE4, 0x8F, - 0x99, 0xF6, 0xE6, 0x9C, 0x97, 0xF6, 0xE6, 0x9C, - 0x9B, 0xF6, 0xE6, 0x9C, 0xA1, 0xF6, 0xE6, 0x9D, - 0x9E, 0xF6, 0xE6, 0x9D, 0x93, 0xF6, 0xF0, 0xA3, - 0x8F, 0x83, 0xF6, 0xE3, 0xAD, 0x89, 0xF6, 0xE6, - 0x9F, 0xBA, 0xF6, 0xE6, 0x9E, 0x85, 0xF6, 0xE6, - 0xA1, 0x92, 0xF6, 0xE6, 0xA2, 0x85, 0xF6, 0xF0, - 0xA3, 0x91, 0xAD, 0xF6, 0xE6, 0xA2, 0x8E, 0xF6, - 0xE6, 0xA0, 0x9F, 0xF6, 0xE6, 0xA4, 0x94, 0xF6, - 0xE3, 0xAE, 0x9D, 0xF6, 0xE6, 0xA5, 0x82, 0xF6, - 0xE6, 0xA6, 0xA3, 0xF6, 0xE6, 0xA7, 0xAA, 0xF6, - 0xE6, 0xAA, 0xA8, 0xF6, 0xF0, 0xA3, 0x9A, 0xA3, - 0xF6, 0xE6, 0xAB, 0x9B, 0xF6, 0xE3, 0xB0, 0x98, - 0xF6, 0xE6, 0xAC, 0xA1, 0xF6, 0xF0, 0xA3, 0xA2, - 0xA7, 0xF6, 0xE6, 0xAD, 0x94, 0xF6, 0xE3, 0xB1, - 0x8E, 0xF6, 0xE6, 0xAD, 0xB2, 0xF6, 0xE6, 0xAE, - 0x9F, 0xF6, 0xE6, 0xAE, 0xBA, 0xF6, 0xE6, 0xAE, - 0xBB, 0xF6, 0xF0, 0xA3, 0xAA, 0x8D, 0xF6, 0xF0, - 0xA1, 0xB4, 0x8B, 0xF6, 0xF0, 0xA3, 0xAB, 0xBA, - 0xF6, 0xE6, 0xB1, 0x8E, 0xF6, 0xF0, 0xA3, 0xB2, - 0xBC, 0xF6, 0xE6, 0xB2, 0xBF, 0xF6, 0xE6, 0xB3, - 0x8D, 0xF6, 0xE6, 0xB1, 0xA7, 0xF6, 0xE6, 0xB4, - 0x96, 0xF6, 0xE6, 0xB4, 0xBE, 0xF6, 0xE6, 0xB5, - 0xB7, 0xF6, 0xE6, 0xB5, 0x81, 0xF6, 0xE6, 0xB5, - 0xA9, 0xF6, 0xE6, 0xB5, 0xB8, 0xF6, 0xE6, 0xB6, - 0x85, 0xF6, 0xF0, 0xA3, 0xB4, 0x9E, 0xF6, 0xE6, - 0xB4, 0xB4, 0xF6, 0xE6, 0xB8, 0xAF, 0xF6, 0xE6, - 0xB9, 0xAE, 0xF6, 0xE3, 0xB4, 0xB3, 0xF6, 0xE6, - 0xBB, 0x8B, 0xF6, 0xE6, 0xBB, 0x87, 0xF6, 0xF0, - 0xA3, 0xBB, 0x91, 0xF6, 0xE6, 0xB7, 0xB9, 0xF6, - 0xE6, 0xBD, 0xAE, 0xF6, 0xF0, 0xA3, 0xBD, 0x9E, - 0xF6, 0xF0, 0xA3, 0xBE, 0x8E, 0xF6, 0xE6, 0xBF, - 0x86, 0xF6, 0xE7, 0x80, 0xB9, 0xF6, 0xE7, 0x80, - 0x9E, 0xF6, 0xE7, 0x80, 0x9B, 0xF6, 0xE3, 0xB6, - 0x96, 0xF6, 0xE7, 0x81, 0x8A, 0xF6, 0xE7, 0x81, - 0xBD, 0xF6, 0xE7, 0x81, 0xB7, 0xF6, 0xE7, 0x82, - 0xAD, 0xF6, 0xF0, 0xA0, 0x94, 0xA5, 0xF6, 0xE7, - 0x85, 0x85, 0xF6, 0xF0, 0xA4, 0x89, 0xA3, 0xF6, - 0xE7, 0x86, 0x9C, 0xF6, 0xF0, 0xA4, 0x8E, 0xAB, - 0xF6, 0xE7, 0x88, 0xA8, 0xF6, 0xE7, 0x88, 0xB5, - 0xF6, 0xE7, 0x89, 0x90, 0xF6, 0xF0, 0xA4, 0x98, - 0x88, 0xF6, 0xE7, 0x8A, 0x80, 0xF6, 0xE7, 0x8A, - 0x95, 0xF6, 0xF0, 0xA4, 0x9C, 0xB5, 0xF6, 0xF0, - 0xA4, 0xA0, 0x94, 0xF6, 0xE7, 0x8D, 0xBA, 0xF6, - 0xE7, 0x8E, 0x8B, 0xF6, 0xE3, 0xBA, 0xAC, 0xF6, - 0xE7, 0x8E, 0xA5, 0xF6, 0xE3, 0xBA, 0xB8, 0xF6, - 0xE3, 0xBA, 0xB8, 0xF6, 0xE7, 0x91, 0x87, 0xF6, - 0xE7, 0x91, 0x9C, 0xF6, 0xE7, 0x91, 0xB1, 0xF6, - 0xE7, 0x92, 0x85, 0xF6, 0xE7, 0x93, 0x8A, 0xF6, - 0xE3, 0xBC, 0x9B, 0xF6, 0xE7, 0x94, 0xA4, 0xF6, - 0xF0, 0xA4, 0xB0, 0xB6, 0xF6, 0xE7, 0x94, 0xBE, - 0xF6, 0xF0, 0xA4, 0xB2, 0x92, 0xF6, 0xE7, 0x95, - 0xB0, 0xF6, 0xF0, 0xA2, 0x86, 0x9F, 0xF6, 0xE7, - 0x98, 0x90, 0xF6, 0xF0, 0xA4, 0xBE, 0xA1, 0xF6, - 0xF0, 0xA4, 0xBE, 0xB8, 0xF6, 0xF0, 0xA5, 0x81, - 0x84, 0xF6, 0xE3, 0xBF, 0xBC, 0xF6, 0xE4, 0x80, - 0x88, 0xF6, 0xE7, 0x9B, 0xB4, 0xF6, 0xF0, 0xA5, - 0x83, 0xB3, 0xF6, 0xF0, 0xA5, 0x83, 0xB2, 0xF6, - 0xF0, 0xA5, 0x84, 0x99, 0xF6, 0xF0, 0xA5, 0x84, - 0xB3, 0xF6, 0xE7, 0x9C, 0x9E, 0xF6, 0xE7, 0x9C, - 0x9F, 0xF6, 0xE7, 0x9C, 0x9F, 0xF6, 0xE7, 0x9D, - 0x8A, 0xF6, 0xE4, 0x80, 0xB9, 0xF6, 0xE7, 0x9E, - 0x8B, 0xF6, 0xE4, 0x81, 0x86, 0xF6, 0xE4, 0x82, - 0x96, 0xF6, 0xF0, 0xA5, 0x90, 0x9D, 0xF6, 0xE7, - 0xA1, 0x8E, 0xF6, 0xE7, 0xA2, 0x8C, 0xF6, 0xE7, - 0xA3, 0x8C, 0xF6, 0xE4, 0x83, 0xA3, 0xF6, 0xF0, - 0xA5, 0x98, 0xA6, 0xF6, 0xE7, 0xA5, 0x96, 0xF6, - 0xF0, 0xA5, 0x9A, 0x9A, 0xF6, 0xF0, 0xA5, 0x9B, - 0x85, 0xF6, 0xE7, 0xA6, 0x8F, 0xF6, 0xE7, 0xA7, - 0xAB, 0xF6, 0xE4, 0x84, 0xAF, 0xF6, 0xE7, 0xA9, - 0x80, 0xF6, 0xE7, 0xA9, 0x8A, 0xF6, 0xE7, 0xA9, - 0x8F, 0xF6, 0xF0, 0xA5, 0xA5, 0xBC, 0xF6, 0xF0, - 0xA5, 0xAA, 0xA7, 0xF6, 0xF0, 0xA5, 0xAA, 0xA7, - 0xF6, 0xE7, 0xAB, 0xAE, 0xF6, 0xE4, 0x88, 0x82, - 0xF6, 0xF0, 0xA5, 0xAE, 0xAB, 0xF6, 0xE7, 0xAF, - 0x86, 0xF6, 0xE7, 0xAF, 0x89, 0xF6, 0xE4, 0x88, - 0xA7, 0xF6, 0xF0, 0xA5, 0xB2, 0x80, 0xF6, 0xE7, - 0xB3, 0x92, 0xF6, 0xE4, 0x8A, 0xA0, 0xF6, 0xE7, - 0xB3, 0xA8, 0xF6, 0xE7, 0xB3, 0xA3, 0xF6, 0xE7, - 0xB4, 0x80, 0xF6, 0xF0, 0xA5, 0xBE, 0x86, 0xF6, - 0xE7, 0xB5, 0xA3, 0xF6, 0xE4, 0x8C, 0x81, 0xF6, - 0xE7, 0xB7, 0x87, 0xF6, 0xE7, 0xB8, 0x82, 0xF6, - 0xE7, 0xB9, 0x85, 0xF6, 0xE4, 0x8C, 0xB4, 0xF6, - 0xF0, 0xA6, 0x88, 0xA8, 0xF6, 0xF0, 0xA6, 0x89, - 0x87, 0xF6, 0xE4, 0x8D, 0x99, 0xF6, 0xF0, 0xA6, - 0x8B, 0x99, 0xF6, 0xE7, 0xBD, 0xBA, 0xF6, 0xF0, - 0xA6, 0x8C, 0xBE, 0xF6, 0xE7, 0xBE, 0x95, 0xF6, - 0xE7, 0xBF, 0xBA, 0xF6, 0xE8, 0x80, 0x85, 0xF6, - 0xF0, 0xA6, 0x93, 0x9A, 0xF6, 0xF0, 0xA6, 0x94, - 0xA3, 0xF6, 0xE8, 0x81, 0xA0, 0xF6, 0xF0, 0xA6, - 0x96, 0xA8, 0xF6, 0xE8, 0x81, 0xB0, 0xF6, 0xF0, - 0xA3, 0x8D, 0x9F, 0xF6, 0xE4, 0x8F, 0x95, 0xF6, - 0xE8, 0x82, 0xB2, 0xF6, 0xE8, 0x84, 0x83, 0xF6, - 0xE4, 0x90, 0x8B, 0xF6, 0xE8, 0x84, 0xBE, 0xF6, - 0xE5, 0xAA, 0xB5, 0xF6, 0xF0, 0xA6, 0x9E, 0xA7, - 0xF6, 0xF0, 0xA6, 0x9E, 0xB5, 0xF6, 0xF0, 0xA3, - 0x8E, 0x93, 0xF6, 0xF0, 0xA3, 0x8E, 0x9C, 0xF6, - 0xE8, 0x88, 0x81, 0xF6, 0xE8, 0x88, 0x84, 0xF6, - 0xE8, 0xBE, 0x9E, 0xF6, 0xE4, 0x91, 0xAB, 0xF6, - 0xE8, 0x8A, 0x91, 0xF6, 0xE8, 0x8A, 0x8B, 0xF6, - 0xE8, 0x8A, 0x9D, 0xF6, 0xE5, 0x8A, 0xB3, 0xF6, - 0xE8, 0x8A, 0xB1, 0xF6, 0xE8, 0x8A, 0xB3, 0xF6, - 0xE8, 0x8A, 0xBD, 0xF6, 0xE8, 0x8B, 0xA6, 0xF6, - 0xF0, 0xA6, 0xAC, 0xBC, 0xF6, 0xE8, 0x8B, 0xA5, - 0xF6, 0xE8, 0x8C, 0x9D, 0xF6, 0xE8, 0x8D, 0xA3, - 0xF6, 0xE8, 0x8E, 0xAD, 0xF6, 0xE8, 0x8C, 0xA3, - 0xF6, 0xE8, 0x8E, 0xBD, 0xF6, 0xE8, 0x8F, 0xA7, - 0xF6, 0xE8, 0x91, 0x97, 0xF6, 0xE8, 0x8D, 0x93, - 0xF6, 0xE8, 0x8F, 0x8A, 0xF6, 0xE8, 0x8F, 0x8C, - 0xF6, 0xE8, 0x8F, 0x9C, 0xF6, 0xF0, 0xA6, 0xB0, - 0xB6, 0xF6, 0xF0, 0xA6, 0xB5, 0xAB, 0xF6, 0xF0, - 0xA6, 0xB3, 0x95, 0xF6, 0xE4, 0x94, 0xAB, 0xF6, - 0xE8, 0x93, 0xB1, 0xF6, 0xE8, 0x93, 0xB3, 0xF6, - 0xE8, 0x94, 0x96, 0xF6, 0xF0, 0xA7, 0x8F, 0x8A, - 0xF6, 0xE8, 0x95, 0xA4, 0xF6, 0xF0, 0xA6, 0xBC, - 0xAC, 0xF6, 0xE4, 0x95, 0x9D, 0xF6, 0xE4, 0x95, - 0xA1, 0xF6, 0xF0, 0xA6, 0xBE, 0xB1, 0xF6, 0xF0, - 0xA7, 0x83, 0x92, 0xF6, 0xE4, 0x95, 0xAB, 0xF6, - 0xE8, 0x99, 0x90, 0xF6, 0xE8, 0x99, 0x9C, 0xF6, - 0xE8, 0x99, 0xA7, 0xF6, 0xE8, 0x99, 0xA9, 0xF6, - 0xE8, 0x9A, 0xA9, 0xF6, 0xE8, 0x9A, 0x88, 0xF6, - 0xE8, 0x9C, 0x8E, 0xF6, 0xE8, 0x9B, 0xA2, 0xF6, - 0xE8, 0x9D, 0xB9, 0xF6, 0xE8, 0x9C, 0xA8, 0xF6, - 0xE8, 0x9D, 0xAB, 0xF6, 0xE8, 0x9E, 0x86, 0xF6, - 0xE4, 0x97, 0x97, 0xF6, 0xE8, 0x9F, 0xA1, 0xF6, - 0xE8, 0xA0, 0x81, 0xF6, 0xE4, 0x97, 0xB9, 0xF6, - 0xE8, 0xA1, 0xA0, 0xF6, 0xE8, 0xA1, 0xA3, 0xF6, - 0xF0, 0xA7, 0x99, 0xA7, 0xF6, 0xE8, 0xA3, 0x97, - 0xF6, 0xE8, 0xA3, 0x9E, 0xF6, 0xE4, 0x98, 0xB5, - 0xF6, 0xE8, 0xA3, 0xBA, 0xF6, 0xE3, 0x92, 0xBB, - 0xF6, 0xF0, 0xA7, 0xA2, 0xAE, 0xF6, 0xF0, 0xA7, - 0xA5, 0xA6, 0xF6, 0xE4, 0x9A, 0xBE, 0xF6, 0xE4, - 0x9B, 0x87, 0xF6, 0xE8, 0xAA, 0xA0, 0xF6, 0xE8, - 0xAB, 0xAD, 0xF6, 0xE8, 0xAE, 0x8A, 0xF6, 0xE8, - 0xB1, 0x95, 0xF6, 0xF0, 0xA7, 0xB2, 0xA8, 0xF6, - 0xE8, 0xB2, 0xAB, 0xF6, 0xE8, 0xB3, 0x81, 0xF6, - 0xE8, 0xB4, 0x9B, 0xF6, 0xE8, 0xB5, 0xB7, 0xF6, - 0xF0, 0xA7, 0xBC, 0xAF, 0xF6, 0xF0, 0xA0, 0xA0, - 0x84, 0xF6, 0xE8, 0xB7, 0x8B, 0xF6, 0xE8, 0xB6, - 0xBC, 0xF6, 0xE8, 0xB7, 0xB0, 0xF6, 0xF0, 0xA0, - 0xA3, 0x9E, 0xF6, 0xE8, 0xBB, 0x94, 0xF6, 0xE8, - 0xBC, 0xB8, 0xF6, 0xF0, 0xA8, 0x97, 0x92, 0xF6, - 0xF0, 0xA8, 0x97, 0xAD, 0xF6, 0xE9, 0x82, 0x94, - 0xF6, 0xE9, 0x83, 0xB1, 0xF6, 0xE9, 0x84, 0x91, - 0xF6, 0xF0, 0xA8, 0x9C, 0xAE, 0xF6, 0xE9, 0x84, - 0x9B, 0xF6, 0xE9, 0x88, 0xB8, 0xF6, 0xE9, 0x8B, - 0x97, 0xF6, 0xE9, 0x8B, 0x98, 0xF6, 0xE9, 0x89, - 0xBC, 0xF6, 0xE9, 0x8F, 0xB9, 0xF6, 0xE9, 0x90, - 0x95, 0xF6, 0xF0, 0xA8, 0xAF, 0xBA, 0xF6, 0xE9, - 0x96, 0x8B, 0xF6, 0xE4, 0xA6, 0x95, 0xF6, 0xE9, - 0x96, 0xB7, 0xF6, 0xF0, 0xA8, 0xB5, 0xB7, 0xF6, - 0xE4, 0xA7, 0xA6, 0xF6, 0xE9, 0x9B, 0x83, 0xF6, - 0xE5, 0xB6, 0xB2, 0xF6, 0xE9, 0x9C, 0xA3, 0xF6, - 0xF0, 0xA9, 0x85, 0x85, 0xF6, 0xF0, 0xA9, 0x88, - 0x9A, 0xF6, 0xE4, 0xA9, 0xAE, 0xF6, 0xE4, 0xA9, - 0xB6, 0xF6, 0xE9, 0x9F, 0xA0, 0xF6, 0xF0, 0xA9, - 0x90, 0x8A, 0xF6, 0xE4, 0xAA, 0xB2, 0xF6, 0xF0, - 0xA9, 0x92, 0x96, 0xF6, 0xE9, 0xA0, 0x8B, 0xF6, - 0xE9, 0xA0, 0x8B, 0xF6, 0xE9, 0xA0, 0xA9, 0xF6, - 0xF0, 0xA9, 0x96, 0xB6, 0xF6, 0xE9, 0xA3, 0xA2, - 0xF6, 0xE4, 0xAC, 0xB3, 0xF6, 0xE9, 0xA4, 0xA9, - 0xF6, 0xE9, 0xA6, 0xA7, 0xF6, 0xE9, 0xA7, 0x82, - 0xF6, 0xE9, 0xA7, 0xBE, 0xF6, 0xE4, 0xAF, 0x8E, - 0xF6, 0xF0, 0xA9, 0xAC, 0xB0, 0xF6, 0xE9, 0xAC, - 0x92, 0xF6, 0xE9, 0xB1, 0x80, 0xF6, 0xE9, 0xB3, - 0xBD, 0xF6, 0xE4, 0xB3, 0x8E, 0xF6, 0xE4, 0xB3, - 0xAD, 0xF6, 0xE9, 0xB5, 0xA7, 0xF6, 0xF0, 0xAA, - 0x83, 0x8E, 0xF6, 0xE4, 0xB3, 0xB8, 0xF6, 0xF0, - 0xAA, 0x84, 0x85, 0xF6, 0xF0, 0xAA, 0x88, 0x8E, - 0xF6, 0xF0, 0xAA, 0x8A, 0x91, 0xF6, 0xE9, 0xBA, - 0xBB, 0xF6, 0xE4, 0xB5, 0x96, 0xF6, 0xE9, 0xBB, - 0xB9, 0xF6, 0xE9, 0xBB, 0xBE, 0xF6, 0xE9, 0xBC, - 0x85, 0xF6, 0xE9, 0xBC, 0x8F, 0xF6, 0xE9, 0xBC, - 0x96, 0xF6, 0xE9, 0xBC, 0xBB, 0xF6, 0xF0, 0xAA, - 0x98, 0x80, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - }, - { - 0x20, 0x20, 0xCC, 0x88, 0x61, 0x20, 0xCC, 0x84, - 0x32, 0x33, 0x20, 0xCC, 0x81, 0xCE, 0xBC, 0x20, - 0xCC, 0xA7, 0x31, 0x6F, 0x31, 0xE2, 0x81, 0x84, - 0x34, 0x31, 0xE2, 0x81, 0x84, 0x32, 0x33, 0xE2, - 0x81, 0x84, 0x34, 0xF6, 0x41, 0xCC, 0x80, 0xF6, - 0x41, 0xCC, 0x81, 0xF6, 0x41, 0xCC, 0x82, 0xF6, - 0x41, 0xCC, 0x83, 0xF6, 0x41, 0xCC, 0x88, 0xF6, - 0x41, 0xCC, 0x8A, 0xF6, 0x43, 0xCC, 0xA7, 0xF6, - 0x45, 0xCC, 0x80, 0xF6, 0x45, 0xCC, 0x81, 0xF6, - 0x45, 0xCC, 0x82, 0xF6, 0x45, 0xCC, 0x88, 0xF6, - 0x49, 0xCC, 0x80, 0xF6, 0x49, 0xCC, 0x81, 0xF6, - 0x49, 0xCC, 0x82, 0xF6, 0x49, 0xCC, 0x88, 0xF6, - 0x4E, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x80, 0xF6, - 0x4F, 0xCC, 0x81, 0xF6, 0x4F, 0xCC, 0x82, 0xF6, - 0x4F, 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x88, 0xF6, - 0x55, 0xCC, 0x80, 0xF6, 0x55, 0xCC, 0x81, 0xF6, - 0x55, 0xCC, 0x82, 0xF6, 0x55, 0xCC, 0x88, 0xF6, - 0x59, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x80, 0xF6, - 0x61, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x82, 0xF6, - 0x61, 0xCC, 0x83, 0xF6, 0x61, 0xCC, 0x88, 0xF6, - 0x61, 0xCC, 0x8A, 0xF6, 0x63, 0xCC, 0xA7, 0xF6, - 0x65, 0xCC, 0x80, 0xF6, 0x65, 0xCC, 0x81, 0xF6, - 0x65, 0xCC, 0x82, 0xF6, 0x65, 0xCC, 0x88, 0xF6, - 0x69, 0xCC, 0x80, 0xF6, 0x69, 0xCC, 0x81, 0xF6, - 0x69, 0xCC, 0x82, 0xF6, 0x69, 0xCC, 0x88, 0xF6, - 0x6E, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x80, 0xF6, - 0x6F, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x82, 0xF6, - 0x6F, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x88, 0xF6, - 0x75, 0xCC, 0x80, 0xF6, 0x75, 0xCC, 0x81, 0xF6, - 0x75, 0xCC, 0x82, 0xF6, 0x75, 0xCC, 0x88, 0xF6, - 0x79, 0xCC, 0x81, 0xF6, 0x79, 0xCC, 0x88, 0xF6, - 0x41, 0xCC, 0x84, 0xF6, 0x61, 0xCC, 0x84, 0xF6, - 0x41, 0xCC, 0x86, 0xF6, 0x61, 0xCC, 0x86, 0xF6, - 0x41, 0xCC, 0xA8, 0xF6, 0x61, 0xCC, 0xA8, 0xF6, - 0x43, 0xCC, 0x81, 0xF6, 0x63, 0xCC, 0x81, 0xF6, - 0x43, 0xCC, 0x82, 0xF6, 0x63, 0xCC, 0x82, 0xF6, - 0x43, 0xCC, 0x87, 0xF6, 0x63, 0xCC, 0x87, 0xF6, - 0x43, 0xCC, 0x8C, 0xF6, 0x63, 0xCC, 0x8C, 0xF6, - 0x44, 0xCC, 0x8C, 0xF6, 0x64, 0xCC, 0x8C, 0xF6, - 0x45, 0xCC, 0x84, 0xF6, 0x65, 0xCC, 0x84, 0xF6, - 0x45, 0xCC, 0x86, 0xF6, 0x65, 0xCC, 0x86, 0xF6, - 0x45, 0xCC, 0x87, 0xF6, 0x65, 0xCC, 0x87, 0xF6, - 0x45, 0xCC, 0xA8, 0xF6, 0x65, 0xCC, 0xA8, 0xF6, - 0x45, 0xCC, 0x8C, 0xF6, 0x65, 0xCC, 0x8C, 0xF6, - 0x47, 0xCC, 0x82, 0xF6, 0x67, 0xCC, 0x82, 0xF6, - 0x47, 0xCC, 0x86, 0xF6, 0x67, 0xCC, 0x86, 0xF6, - 0x47, 0xCC, 0x87, 0xF6, 0x67, 0xCC, 0x87, 0xF6, - 0x47, 0xCC, 0xA7, 0xF6, 0x67, 0xCC, 0xA7, 0xF6, - 0x48, 0xCC, 0x82, 0xF6, 0x68, 0xCC, 0x82, 0xF6, - 0x49, 0xCC, 0x83, 0xF6, 0x69, 0xCC, 0x83, 0xF6, - 0x49, 0xCC, 0x84, 0xF6, 0x69, 0xCC, 0x84, 0xF6, - 0x49, 0xCC, 0x86, 0xF6, 0x69, 0xCC, 0x86, 0xF6, - 0x49, 0xCC, 0xA8, 0xF6, 0x69, 0xCC, 0xA8, 0xF6, - 0x49, 0xCC, 0x87, 0x49, 0x4A, 0x69, 0x6A, 0xF6, - 0x4A, 0xCC, 0x82, 0xF6, 0x6A, 0xCC, 0x82, 0xF6, - 0x4B, 0xCC, 0xA7, 0xF6, 0x6B, 0xCC, 0xA7, 0xF6, - 0x4C, 0xCC, 0x81, 0xF6, 0x6C, 0xCC, 0x81, 0xF6, - 0x4C, 0xCC, 0xA7, 0xF6, 0x6C, 0xCC, 0xA7, 0xF6, - 0x4C, 0xCC, 0x8C, 0xF6, 0x6C, 0xCC, 0x8C, 0x4C, - 0xC2, 0xB7, 0x6C, 0xC2, 0xB7, 0xF6, 0x4E, 0xCC, - 0x81, 0xF6, 0x6E, 0xCC, 0x81, 0xF6, 0x4E, 0xCC, - 0xA7, 0xF6, 0x6E, 0xCC, 0xA7, 0xF6, 0x4E, 0xCC, - 0x8C, 0xF6, 0x6E, 0xCC, 0x8C, 0xCA, 0xBC, 0x6E, - 0xF6, 0x4F, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, 0x84, - 0xF6, 0x4F, 0xCC, 0x86, 0xF6, 0x6F, 0xCC, 0x86, - 0xF6, 0x4F, 0xCC, 0x8B, 0xF6, 0x6F, 0xCC, 0x8B, - 0xF6, 0x52, 0xCC, 0x81, 0xF6, 0x72, 0xCC, 0x81, - 0xF6, 0x52, 0xCC, 0xA7, 0xF6, 0x72, 0xCC, 0xA7, - 0xF6, 0x52, 0xCC, 0x8C, 0xF6, 0x72, 0xCC, 0x8C, - 0xF6, 0x53, 0xCC, 0x81, 0xF6, 0x73, 0xCC, 0x81, - 0xF6, 0x53, 0xCC, 0x82, 0xF6, 0x73, 0xCC, 0x82, - 0xF6, 0x53, 0xCC, 0xA7, 0xF6, 0x73, 0xCC, 0xA7, - 0xF6, 0x53, 0xCC, 0x8C, 0xF6, 0x73, 0xCC, 0x8C, - 0xF6, 0x54, 0xCC, 0xA7, 0xF6, 0x74, 0xCC, 0xA7, - 0xF6, 0x54, 0xCC, 0x8C, 0xF6, 0x74, 0xCC, 0x8C, - 0xF6, 0x55, 0xCC, 0x83, 0xF6, 0x75, 0xCC, 0x83, - 0xF6, 0x55, 0xCC, 0x84, 0xF6, 0x75, 0xCC, 0x84, - 0xF6, 0x55, 0xCC, 0x86, 0xF6, 0x75, 0xCC, 0x86, - 0xF6, 0x55, 0xCC, 0x8A, 0xF6, 0x75, 0xCC, 0x8A, - 0xF6, 0x55, 0xCC, 0x8B, 0xF6, 0x75, 0xCC, 0x8B, - 0xF6, 0x55, 0xCC, 0xA8, 0xF6, 0x75, 0xCC, 0xA8, - 0xF6, 0x57, 0xCC, 0x82, 0xF6, 0x77, 0xCC, 0x82, - 0xF6, 0x59, 0xCC, 0x82, 0xF6, 0x79, 0xCC, 0x82, - 0xF6, 0x59, 0xCC, 0x88, 0xF6, 0x5A, 0xCC, 0x81, - 0xF6, 0x7A, 0xCC, 0x81, 0xF6, 0x5A, 0xCC, 0x87, - 0xF6, 0x7A, 0xCC, 0x87, 0xF6, 0x5A, 0xCC, 0x8C, - 0xF6, 0x7A, 0xCC, 0x8C, 0x73, 0xF6, 0x4F, 0xCC, - 0x9B, 0xF6, 0x6F, 0xCC, 0x9B, 0xF6, 0x55, 0xCC, - 0x9B, 0xF6, 0x75, 0xCC, 0x9B, 0x44, 0x5A, 0xCC, - 0x8C, 0x44, 0x7A, 0xCC, 0x8C, 0x64, 0x7A, 0xCC, - 0x8C, 0x4C, 0x4A, 0x4C, 0x6A, 0x6C, 0x6A, 0x4E, - 0x4A, 0x4E, 0x6A, 0x6E, 0x6A, 0xF6, 0x41, 0xCC, - 0x8C, 0xF6, 0x61, 0xCC, 0x8C, 0xF6, 0x49, 0xCC, - 0x8C, 0xF6, 0x69, 0xCC, 0x8C, 0xF6, 0x4F, 0xCC, - 0x8C, 0xF6, 0x6F, 0xCC, 0x8C, 0xF6, 0x55, 0xCC, - 0x8C, 0xF6, 0x75, 0xCC, 0x8C, 0xF6, 0x55, 0xCC, - 0x88, 0xCC, 0x84, 0xF6, 0x75, 0xCC, 0x88, 0xCC, - 0x84, 0xF6, 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xF6, - 0x75, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0x55, 0xCC, - 0x88, 0xCC, 0x8C, 0xF6, 0x75, 0xCC, 0x88, 0xCC, - 0x8C, 0xF6, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xF6, - 0x75, 0xCC, 0x88, 0xCC, 0x80, 0xF6, 0x41, 0xCC, - 0x88, 0xCC, 0x84, 0xF6, 0x61, 0xCC, 0x88, 0xCC, - 0x84, 0xF6, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xF6, - 0x61, 0xCC, 0x87, 0xCC, 0x84, 0xF6, 0xC3, 0x86, - 0xCC, 0x84, 0xF6, 0xC3, 0xA6, 0xCC, 0x84, 0xF6, - 0x47, 0xCC, 0x8C, 0xF6, 0x67, 0xCC, 0x8C, 0xF6, - 0x4B, 0xCC, 0x8C, 0xF6, 0x6B, 0xCC, 0x8C, 0xF6, - 0x4F, 0xCC, 0xA8, 0xF6, 0x6F, 0xCC, 0xA8, 0xF6, - 0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, - 0xA8, 0xCC, 0x84, 0xF6, 0xC6, 0xB7, 0xCC, 0x8C, - 0xF6, 0xCA, 0x92, 0xCC, 0x8C, 0xF6, 0x6A, 0xCC, - 0x8C, 0x44, 0x5A, 0x44, 0x7A, 0x64, 0x7A, 0xF6, - 0x47, 0xCC, 0x81, 0xF6, 0x67, 0xCC, 0x81, 0xF6, - 0x4E, 0xCC, 0x80, 0xF6, 0x6E, 0xCC, 0x80, 0xF6, - 0x41, 0xCC, 0x8A, 0xCC, 0x81, 0xF6, 0x61, 0xCC, - 0x8A, 0xCC, 0x81, 0xF6, 0xC3, 0x86, 0xCC, 0x81, - 0xF6, 0xC3, 0xA6, 0xCC, 0x81, 0xF6, 0xC3, 0x98, - 0xCC, 0x81, 0xF6, 0xC3, 0xB8, 0xCC, 0x81, 0xF6, - 0x41, 0xCC, 0x8F, 0xF6, 0x61, 0xCC, 0x8F, 0xF6, - 0x41, 0xCC, 0x91, 0xF6, 0x61, 0xCC, 0x91, 0xF6, - 0x45, 0xCC, 0x8F, 0xF6, 0x65, 0xCC, 0x8F, 0xF6, - 0x45, 0xCC, 0x91, 0xF6, 0x65, 0xCC, 0x91, 0xF6, - 0x49, 0xCC, 0x8F, 0xF6, 0x69, 0xCC, 0x8F, 0xF6, - 0x49, 0xCC, 0x91, 0xF6, 0x69, 0xCC, 0x91, 0xF6, - 0x4F, 0xCC, 0x8F, 0xF6, 0x6F, 0xCC, 0x8F, 0xF6, - 0x4F, 0xCC, 0x91, 0xF6, 0x6F, 0xCC, 0x91, 0xF6, - 0x52, 0xCC, 0x8F, 0xF6, 0x72, 0xCC, 0x8F, 0xF6, - 0x52, 0xCC, 0x91, 0xF6, 0x72, 0xCC, 0x91, 0xF6, - 0x55, 0xCC, 0x8F, 0xF6, 0x75, 0xCC, 0x8F, 0xF6, - 0x55, 0xCC, 0x91, 0xF6, 0x75, 0xCC, 0x91, 0xF6, - 0x53, 0xCC, 0xA6, 0xF6, 0x73, 0xCC, 0xA6, 0xF6, - 0x54, 0xCC, 0xA6, 0xF6, 0x74, 0xCC, 0xA6, 0xF6, - 0x48, 0xCC, 0x8C, 0xF6, 0x68, 0xCC, 0x8C, 0xF6, - 0x41, 0xCC, 0x87, 0xF6, 0x61, 0xCC, 0x87, 0xF6, - 0x45, 0xCC, 0xA7, 0xF6, 0x65, 0xCC, 0xA7, 0xF6, - 0x4F, 0xCC, 0x88, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, - 0x88, 0xCC, 0x84, 0xF6, 0x4F, 0xCC, 0x83, 0xCC, - 0x84, 0xF6, 0x6F, 0xCC, 0x83, 0xCC, 0x84, 0xF6, - 0x4F, 0xCC, 0x87, 0xF6, 0x6F, 0xCC, 0x87, 0xF6, - 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xF6, 0x6F, 0xCC, - 0x87, 0xCC, 0x84, 0xF6, 0x59, 0xCC, 0x84, 0xF6, - 0x79, 0xCC, 0x84, 0x68, 0xC9, 0xA6, 0x6A, 0x72, - 0xC9, 0xB9, 0xC9, 0xBB, 0xCA, 0x81, 0x77, 0x79, - 0x20, 0xCC, 0x86, 0x20, 0xCC, 0x87, 0x20, 0xCC, - 0x8A, 0x20, 0xCC, 0xA8, 0x20, 0xCC, 0x83, 0x20, - 0xCC, 0x8B, 0xC9, 0xA3, 0x6C, 0x73, 0x78, 0xCA, - 0x95, 0xF6, 0xCC, 0x80, 0xF6, 0xCC, 0x81, 0xF6, - 0xCC, 0x93, 0xF6, 0xCC, 0x88, 0xCC, 0x81, 0xF6, - 0xCA, 0xB9, 0x20, 0xCD, 0x85, 0xF6, 0x3B, 0x20, - 0xCC, 0x81, 0xF5, 0x05, 0xC2, 0xA8, 0xCC, 0x81, - 0x20, 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0xCE, 0x91, - 0xCC, 0x81, 0xF6, 0xC2, 0xB7, 0xF6, 0xCE, 0x95, - 0xCC, 0x81, 0xF6, 0xCE, 0x97, 0xCC, 0x81, 0xF6, - 0xCE, 0x99, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, - 0x81, 0xF6, 0xCE, 0xA5, 0xCC, 0x81, 0xF6, 0xCE, - 0xA9, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x88, - 0xCC, 0x81, 0xF6, 0xCE, 0x99, 0xCC, 0x88, 0xF6, - 0xCE, 0xA5, 0xCC, 0x88, 0xF6, 0xCE, 0xB1, 0xCC, - 0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x81, 0xF6, 0xCE, - 0xB7, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, 0x81, - 0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xF6, - 0xCE, 0xB9, 0xCC, 0x88, 0xF6, 0xCF, 0x85, 0xCC, - 0x88, 0xF6, 0xCE, 0xBF, 0xCC, 0x81, 0xF6, 0xCF, - 0x85, 0xCC, 0x81, 0xF6, 0xCF, 0x89, 0xCC, 0x81, - 0xCE, 0xB2, 0xCE, 0xB8, 0xCE, 0xA5, 0xF5, 0x05, - 0xCF, 0x92, 0xCC, 0x81, 0xCE, 0xA5, 0xCC, 0x81, - 0xF5, 0x05, 0xCF, 0x92, 0xCC, 0x88, 0xCE, 0xA5, - 0xCC, 0x88, 0xCF, 0x86, 0xCF, 0x80, 0xCE, 0xBA, - 0xCF, 0x81, 0xCF, 0x82, 0xCE, 0x98, 0xCE, 0xB5, - 0xCE, 0xA3, 0xF6, 0xD0, 0x95, 0xCC, 0x80, 0xF6, - 0xD0, 0x95, 0xCC, 0x88, 0xF6, 0xD0, 0x93, 0xCC, - 0x81, 0xF6, 0xD0, 0x86, 0xCC, 0x88, 0xF6, 0xD0, - 0x9A, 0xCC, 0x81, 0xF6, 0xD0, 0x98, 0xCC, 0x80, - 0xF6, 0xD0, 0xA3, 0xCC, 0x86, 0xF6, 0xD0, 0x98, - 0xCC, 0x86, 0xF6, 0xD0, 0xB8, 0xCC, 0x86, 0xF6, - 0xD0, 0xB5, 0xCC, 0x80, 0xF6, 0xD0, 0xB5, 0xCC, - 0x88, 0xF6, 0xD0, 0xB3, 0xCC, 0x81, 0xF6, 0xD1, - 0x96, 0xCC, 0x88, 0xF6, 0xD0, 0xBA, 0xCC, 0x81, - 0xF6, 0xD0, 0xB8, 0xCC, 0x80, 0xF6, 0xD1, 0x83, - 0xCC, 0x86, 0xF6, 0xD1, 0xB4, 0xCC, 0x8F, 0xF6, - 0xD1, 0xB5, 0xCC, 0x8F, 0xF6, 0xD0, 0x96, 0xCC, - 0x86, 0xF6, 0xD0, 0xB6, 0xCC, 0x86, 0xF6, 0xD0, - 0x90, 0xCC, 0x86, 0xF6, 0xD0, 0xB0, 0xCC, 0x86, - 0xF6, 0xD0, 0x90, 0xCC, 0x88, 0xF6, 0xD0, 0xB0, - 0xCC, 0x88, 0xF6, 0xD0, 0x95, 0xCC, 0x86, 0xF6, - 0xD0, 0xB5, 0xCC, 0x86, 0xF6, 0xD3, 0x98, 0xCC, - 0x88, 0xF6, 0xD3, 0x99, 0xCC, 0x88, 0xF6, 0xD0, - 0x96, 0xCC, 0x88, 0xF6, 0xD0, 0xB6, 0xCC, 0x88, - 0xF6, 0xD0, 0x97, 0xCC, 0x88, 0xF6, 0xD0, 0xB7, - 0xCC, 0x88, 0xF6, 0xD0, 0x98, 0xCC, 0x84, 0xF6, - 0xD0, 0xB8, 0xCC, 0x84, 0xF6, 0xD0, 0x98, 0xCC, - 0x88, 0xF6, 0xD0, 0xB8, 0xCC, 0x88, 0xF6, 0xD0, - 0x9E, 0xCC, 0x88, 0xF6, 0xD0, 0xBE, 0xCC, 0x88, - 0xF6, 0xD3, 0xA8, 0xCC, 0x88, 0xF6, 0xD3, 0xA9, - 0xCC, 0x88, 0xF6, 0xD0, 0xAD, 0xCC, 0x88, 0xF6, - 0xD1, 0x8D, 0xCC, 0x88, 0xF6, 0xD0, 0xA3, 0xCC, - 0x84, 0xF6, 0xD1, 0x83, 0xCC, 0x84, 0xF6, 0xD0, - 0xA3, 0xCC, 0x88, 0xF6, 0xD1, 0x83, 0xCC, 0x88, - 0xF6, 0xD0, 0xA3, 0xCC, 0x8B, 0xF6, 0xD1, 0x83, - 0xCC, 0x8B, 0xF6, 0xD0, 0xA7, 0xCC, 0x88, 0xF6, - 0xD1, 0x87, 0xCC, 0x88, 0xF6, 0xD0, 0xAB, 0xCC, - 0x88, 0xF6, 0xD1, 0x8B, 0xCC, 0x88, 0xD5, 0xA5, - 0xD6, 0x82, 0xF6, 0xD8, 0xA7, 0xD9, 0x93, 0xF6, - 0xD8, 0xA7, 0xD9, 0x94, 0xF6, 0xD9, 0x88, 0xD9, - 0x94, 0xF6, 0xD8, 0xA7, 0xD9, 0x95, 0xF6, 0xD9, - 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0xB4, 0xD9, - 0x88, 0xD9, 0xB4, 0xDB, 0x87, 0xD9, 0xB4, 0xD9, - 0x8A, 0xD9, 0xB4, 0xF6, 0xDB, 0x95, 0xD9, 0x94, - 0xF6, 0xDB, 0x81, 0xD9, 0x94, 0xF6, 0xDB, 0x92, - 0xD9, 0x94, 0xF6, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, - 0xBC, 0xF6, 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, - 0xF6, 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0xF6, - 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, - 0xA4, 0x96, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, - 0x97, 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0x9C, - 0xE0, 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0xA1, 0xE0, - 0xA4, 0xBC, 0xF6, 0xE0, 0xA4, 0xA2, 0xE0, 0xA4, - 0xBC, 0xF6, 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xBC, - 0xF6, 0xE0, 0xA4, 0xAF, 0xE0, 0xA4, 0xBC, 0xF6, - 0xE0, 0xA7, 0x87, 0xE0, 0xA6, 0xBE, 0xF6, 0xE0, - 0xA7, 0x87, 0xE0, 0xA7, 0x97, 0xF6, 0xE0, 0xA6, - 0xA1, 0xE0, 0xA6, 0xBC, 0xF6, 0xE0, 0xA6, 0xA2, - 0xE0, 0xA6, 0xBC, 0xF6, 0xE0, 0xA6, 0xAF, 0xE0, - 0xA6, 0xBC, 0xF6, 0xE0, 0xA8, 0xB2, 0xE0, 0xA8, - 0xBC, 0xF6, 0xE0, 0xA8, 0xB8, 0xE0, 0xA8, 0xBC, - 0xF6, 0xE0, 0xA8, 0x96, 0xE0, 0xA8, 0xBC, 0xF6, - 0xE0, 0xA8, 0x97, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, - 0xA8, 0x9C, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xA8, - 0xAB, 0xE0, 0xA8, 0xBC, 0xF6, 0xE0, 0xAD, 0x87, - 0xE0, 0xAD, 0x96, 0xF6, 0xE0, 0xAD, 0x87, 0xE0, - 0xAC, 0xBE, 0xF6, 0xE0, 0xAD, 0x87, 0xE0, 0xAD, - 0x97, 0xF6, 0xE0, 0xAC, 0xA1, 0xE0, 0xAC, 0xBC, - 0xF6, 0xE0, 0xAC, 0xA2, 0xE0, 0xAC, 0xBC, 0xF6, - 0xE0, 0xAE, 0x92, 0xE0, 0xAF, 0x97, 0xF6, 0xE0, - 0xAF, 0x86, 0xE0, 0xAE, 0xBE, 0xF6, 0xE0, 0xAF, - 0x87, 0xE0, 0xAE, 0xBE, 0xF6, 0xE0, 0xAF, 0x86, - 0xE0, 0xAF, 0x97, 0xF6, 0xE0, 0xB1, 0x86, 0xE0, - 0xB1, 0x96, 0xF6, 0xE0, 0xB2, 0xBF, 0xE0, 0xB3, - 0x95, 0xF6, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x95, - 0xF6, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0xF6, - 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xF6, 0xE0, - 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3, 0x95, - 0xF6, 0xE0, 0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0xF6, - 0xE0, 0xB5, 0x87, 0xE0, 0xB4, 0xBE, 0xF6, 0xE0, - 0xB5, 0x86, 0xE0, 0xB5, 0x97, 0xF6, 0xE0, 0xB7, - 0x99, 0xE0, 0xB7, 0x8A, 0xF6, 0xE0, 0xB7, 0x99, - 0xE0, 0xB7, 0x8F, 0xF6, 0xE0, 0xB7, 0x99, 0xE0, - 0xB7, 0x8F, 0xE0, 0xB7, 0x8A, 0xF6, 0xE0, 0xB7, - 0x99, 0xE0, 0xB7, 0x9F, 0xE0, 0xB9, 0x8D, 0xE0, - 0xB8, 0xB2, 0xE0, 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, - 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0x99, 0xE0, 0xBA, - 0xAB, 0xE0, 0xBA, 0xA1, 0xE0, 0xBC, 0x8B, 0xF6, - 0xE0, 0xBD, 0x82, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, - 0xBD, 0x8C, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, - 0x91, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x96, - 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x9B, 0xE0, - 0xBE, 0xB7, 0xF6, 0xE0, 0xBD, 0x80, 0xE0, 0xBE, - 0xB5, 0xF6, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB2, - 0xF6, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB4, 0xF6, - 0xE0, 0xBE, 0xB2, 0xE0, 0xBE, 0x80, 0xE0, 0xBE, - 0xB2, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6, - 0xE0, 0xBE, 0xB3, 0xE0, 0xBE, 0x80, 0xE0, 0xBE, - 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6, - 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xF6, 0xE0, - 0xBE, 0x92, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, - 0x9C, 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0xA1, - 0xE0, 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0xA6, 0xE0, - 0xBE, 0xB7, 0xF6, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, - 0xB7, 0xF6, 0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, - 0xF6, 0xE1, 0x80, 0xA5, 0xE1, 0x80, 0xAE, 0xE1, - 0x83, 0x9C, 0xF6, 0xE1, 0xAC, 0x85, 0xE1, 0xAC, - 0xB5, 0xF6, 0xE1, 0xAC, 0x87, 0xE1, 0xAC, 0xB5, - 0xF6, 0xE1, 0xAC, 0x89, 0xE1, 0xAC, 0xB5, 0xF6, - 0xE1, 0xAC, 0x8B, 0xE1, 0xAC, 0xB5, 0xF6, 0xE1, - 0xAC, 0x8D, 0xE1, 0xAC, 0xB5, 0xF6, 0xE1, 0xAC, - 0x91, 0xE1, 0xAC, 0xB5, 0xF6, 0xE1, 0xAC, 0xBA, - 0xE1, 0xAC, 0xB5, 0xF6, 0xE1, 0xAC, 0xBC, 0xE1, - 0xAC, 0xB5, 0xF6, 0xE1, 0xAC, 0xBE, 0xE1, 0xAC, - 0xB5, 0xF6, 0xE1, 0xAC, 0xBF, 0xE1, 0xAC, 0xB5, - 0xF6, 0xE1, 0xAD, 0x82, 0xE1, 0xAC, 0xB5, 0x41, - 0xC3, 0x86, 0x42, 0x44, 0x45, 0xC6, 0x8E, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0xC8, 0xA2, 0x50, 0x52, 0x54, 0x55, 0x57, 0x61, - 0xC9, 0x90, 0xC9, 0x91, 0xE1, 0xB4, 0x82, 0x62, - 0x64, 0x65, 0xC9, 0x99, 0xC9, 0x9B, 0xC9, 0x9C, - 0x67, 0x6B, 0x6D, 0xC5, 0x8B, 0x6F, 0xC9, 0x94, - 0xE1, 0xB4, 0x96, 0xE1, 0xB4, 0x97, 0x70, 0x74, - 0x75, 0xE1, 0xB4, 0x9D, 0xC9, 0xAF, 0x76, 0xE1, - 0xB4, 0xA5, 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, - 0xCF, 0x86, 0xCF, 0x87, 0x69, 0x72, 0x75, 0x76, - 0xCE, 0xB2, 0xCE, 0xB3, 0xCF, 0x81, 0xCF, 0x86, - 0xCF, 0x87, 0xD0, 0xBD, 0xC9, 0x92, 0x63, 0xC9, - 0x95, 0xC3, 0xB0, 0xC9, 0x9C, 0x66, 0xC9, 0x9F, - 0xC9, 0xA1, 0xC9, 0xA5, 0xC9, 0xA8, 0xC9, 0xA9, - 0xC9, 0xAA, 0xE1, 0xB5, 0xBB, 0xCA, 0x9D, 0xC9, - 0xAD, 0xE1, 0xB6, 0x85, 0xCA, 0x9F, 0xC9, 0xB1, - 0xC9, 0xB0, 0xC9, 0xB2, 0xC9, 0xB3, 0xC9, 0xB4, - 0xC9, 0xB5, 0xC9, 0xB8, 0xCA, 0x82, 0xCA, 0x83, - 0xC6, 0xAB, 0xCA, 0x89, 0xCA, 0x8A, 0xE1, 0xB4, - 0x9C, 0xCA, 0x8B, 0xCA, 0x8C, 0x7A, 0xCA, 0x90, - 0xCA, 0x91, 0xCA, 0x92, 0xCE, 0xB8, 0xF6, 0x41, - 0xCC, 0xA5, 0xF6, 0x61, 0xCC, 0xA5, 0xF6, 0x42, - 0xCC, 0x87, 0xF6, 0x62, 0xCC, 0x87, 0xF6, 0x42, - 0xCC, 0xA3, 0xF6, 0x62, 0xCC, 0xA3, 0xF6, 0x42, - 0xCC, 0xB1, 0xF6, 0x62, 0xCC, 0xB1, 0xF6, 0x43, - 0xCC, 0xA7, 0xCC, 0x81, 0xF6, 0x63, 0xCC, 0xA7, - 0xCC, 0x81, 0xF6, 0x44, 0xCC, 0x87, 0xF6, 0x64, - 0xCC, 0x87, 0xF6, 0x44, 0xCC, 0xA3, 0xF6, 0x64, - 0xCC, 0xA3, 0xF6, 0x44, 0xCC, 0xB1, 0xF6, 0x64, - 0xCC, 0xB1, 0xF6, 0x44, 0xCC, 0xA7, 0xF6, 0x64, - 0xCC, 0xA7, 0xF6, 0x44, 0xCC, 0xAD, 0xF6, 0x64, - 0xCC, 0xAD, 0xF6, 0x45, 0xCC, 0x84, 0xCC, 0x80, - 0xF6, 0x65, 0xCC, 0x84, 0xCC, 0x80, 0xF6, 0x45, - 0xCC, 0x84, 0xCC, 0x81, 0xF6, 0x65, 0xCC, 0x84, - 0xCC, 0x81, 0xF6, 0x45, 0xCC, 0xAD, 0xF6, 0x65, - 0xCC, 0xAD, 0xF6, 0x45, 0xCC, 0xB0, 0xF6, 0x65, - 0xCC, 0xB0, 0xF6, 0x45, 0xCC, 0xA7, 0xCC, 0x86, - 0xF6, 0x65, 0xCC, 0xA7, 0xCC, 0x86, 0xF6, 0x46, - 0xCC, 0x87, 0xF6, 0x66, 0xCC, 0x87, 0xF6, 0x47, - 0xCC, 0x84, 0xF6, 0x67, 0xCC, 0x84, 0xF6, 0x48, - 0xCC, 0x87, 0xF6, 0x68, 0xCC, 0x87, 0xF6, 0x48, - 0xCC, 0xA3, 0xF6, 0x68, 0xCC, 0xA3, 0xF6, 0x48, - 0xCC, 0x88, 0xF6, 0x68, 0xCC, 0x88, 0xF6, 0x48, - 0xCC, 0xA7, 0xF6, 0x68, 0xCC, 0xA7, 0xF6, 0x48, - 0xCC, 0xAE, 0xF6, 0x68, 0xCC, 0xAE, 0xF6, 0x49, - 0xCC, 0xB0, 0xF6, 0x69, 0xCC, 0xB0, 0xF6, 0x49, - 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0x69, 0xCC, 0x88, - 0xCC, 0x81, 0xF6, 0x4B, 0xCC, 0x81, 0xF6, 0x6B, - 0xCC, 0x81, 0xF6, 0x4B, 0xCC, 0xA3, 0xF6, 0x6B, - 0xCC, 0xA3, 0xF6, 0x4B, 0xCC, 0xB1, 0xF6, 0x6B, - 0xCC, 0xB1, 0xF6, 0x4C, 0xCC, 0xA3, 0xF6, 0x6C, - 0xCC, 0xA3, 0xF6, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, - 0xF6, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xF6, 0x4C, - 0xCC, 0xB1, 0xF6, 0x6C, 0xCC, 0xB1, 0xF6, 0x4C, - 0xCC, 0xAD, 0xF6, 0x6C, 0xCC, 0xAD, 0xF6, 0x4D, - 0xCC, 0x81, 0xF6, 0x6D, 0xCC, 0x81, 0xF6, 0x4D, - 0xCC, 0x87, 0xF6, 0x6D, 0xCC, 0x87, 0xF6, 0x4D, - 0xCC, 0xA3, 0xF6, 0x6D, 0xCC, 0xA3, 0xF6, 0x4E, - 0xCC, 0x87, 0xF6, 0x6E, 0xCC, 0x87, 0xF6, 0x4E, - 0xCC, 0xA3, 0xF6, 0x6E, 0xCC, 0xA3, 0xF6, 0x4E, - 0xCC, 0xB1, 0xF6, 0x6E, 0xCC, 0xB1, 0xF6, 0x4E, - 0xCC, 0xAD, 0xF6, 0x6E, 0xCC, 0xAD, 0xF6, 0x4F, - 0xCC, 0x83, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x83, - 0xCC, 0x81, 0xF6, 0x4F, 0xCC, 0x83, 0xCC, 0x88, - 0xF6, 0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xF6, 0x4F, - 0xCC, 0x84, 0xCC, 0x80, 0xF6, 0x6F, 0xCC, 0x84, - 0xCC, 0x80, 0xF6, 0x4F, 0xCC, 0x84, 0xCC, 0x81, - 0xF6, 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xF6, 0x50, - 0xCC, 0x81, 0xF6, 0x70, 0xCC, 0x81, 0xF6, 0x50, - 0xCC, 0x87, 0xF6, 0x70, 0xCC, 0x87, 0xF6, 0x52, - 0xCC, 0x87, 0xF6, 0x72, 0xCC, 0x87, 0xF6, 0x52, - 0xCC, 0xA3, 0xF6, 0x72, 0xCC, 0xA3, 0xF6, 0x52, - 0xCC, 0xA3, 0xCC, 0x84, 0xF6, 0x72, 0xCC, 0xA3, - 0xCC, 0x84, 0xF6, 0x52, 0xCC, 0xB1, 0xF6, 0x72, - 0xCC, 0xB1, 0xF6, 0x53, 0xCC, 0x87, 0xF6, 0x73, - 0xCC, 0x87, 0xF6, 0x53, 0xCC, 0xA3, 0xF6, 0x73, - 0xCC, 0xA3, 0xF6, 0x53, 0xCC, 0x81, 0xCC, 0x87, - 0xF6, 0x73, 0xCC, 0x81, 0xCC, 0x87, 0xF6, 0x53, - 0xCC, 0x8C, 0xCC, 0x87, 0xF6, 0x73, 0xCC, 0x8C, - 0xCC, 0x87, 0xF6, 0x53, 0xCC, 0xA3, 0xCC, 0x87, - 0xF6, 0x73, 0xCC, 0xA3, 0xCC, 0x87, 0xF6, 0x54, - 0xCC, 0x87, 0xF6, 0x74, 0xCC, 0x87, 0xF6, 0x54, - 0xCC, 0xA3, 0xF6, 0x74, 0xCC, 0xA3, 0xF6, 0x54, - 0xCC, 0xB1, 0xF6, 0x74, 0xCC, 0xB1, 0xF6, 0x54, - 0xCC, 0xAD, 0xF6, 0x74, 0xCC, 0xAD, 0xF6, 0x55, - 0xCC, 0xA4, 0xF6, 0x75, 0xCC, 0xA4, 0xF6, 0x55, - 0xCC, 0xB0, 0xF6, 0x75, 0xCC, 0xB0, 0xF6, 0x55, - 0xCC, 0xAD, 0xF6, 0x75, 0xCC, 0xAD, 0xF6, 0x55, - 0xCC, 0x83, 0xCC, 0x81, 0xF6, 0x75, 0xCC, 0x83, - 0xCC, 0x81, 0xF6, 0x55, 0xCC, 0x84, 0xCC, 0x88, - 0xF6, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xF6, 0x56, - 0xCC, 0x83, 0xF6, 0x76, 0xCC, 0x83, 0xF6, 0x56, - 0xCC, 0xA3, 0xF6, 0x76, 0xCC, 0xA3, 0xF6, 0x57, - 0xCC, 0x80, 0xF6, 0x77, 0xCC, 0x80, 0xF6, 0x57, - 0xCC, 0x81, 0xF6, 0x77, 0xCC, 0x81, 0xF6, 0x57, - 0xCC, 0x88, 0xF6, 0x77, 0xCC, 0x88, 0xF6, 0x57, - 0xCC, 0x87, 0xF6, 0x77, 0xCC, 0x87, 0xF6, 0x57, - 0xCC, 0xA3, 0xF6, 0x77, 0xCC, 0xA3, 0xF6, 0x58, - 0xCC, 0x87, 0xF6, 0x78, 0xCC, 0x87, 0xF6, 0x58, - 0xCC, 0x88, 0xF6, 0x78, 0xCC, 0x88, 0xF6, 0x59, - 0xCC, 0x87, 0xF6, 0x79, 0xCC, 0x87, 0xF6, 0x5A, - 0xCC, 0x82, 0xF6, 0x7A, 0xCC, 0x82, 0xF6, 0x5A, - 0xCC, 0xA3, 0xF6, 0x7A, 0xCC, 0xA3, 0xF6, 0x5A, - 0xCC, 0xB1, 0xF6, 0x7A, 0xCC, 0xB1, 0xF6, 0x68, - 0xCC, 0xB1, 0xF6, 0x74, 0xCC, 0x88, 0xF6, 0x77, - 0xCC, 0x8A, 0xF6, 0x79, 0xCC, 0x8A, 0x61, 0xCA, - 0xBE, 0xF5, 0x05, 0xC5, 0xBF, 0xCC, 0x87, 0x73, - 0xCC, 0x87, 0xF6, 0x41, 0xCC, 0xA3, 0xF6, 0x61, - 0xCC, 0xA3, 0xF6, 0x41, 0xCC, 0x89, 0xF6, 0x61, - 0xCC, 0x89, 0xF6, 0x41, 0xCC, 0x82, 0xCC, 0x81, - 0xF6, 0x61, 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x41, - 0xCC, 0x82, 0xCC, 0x80, 0xF6, 0x61, 0xCC, 0x82, - 0xCC, 0x80, 0xF6, 0x41, 0xCC, 0x82, 0xCC, 0x89, - 0xF6, 0x61, 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x41, - 0xCC, 0x82, 0xCC, 0x83, 0xF6, 0x61, 0xCC, 0x82, - 0xCC, 0x83, 0xF6, 0x41, 0xCC, 0xA3, 0xCC, 0x82, - 0xF6, 0x61, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x41, - 0xCC, 0x86, 0xCC, 0x81, 0xF6, 0x61, 0xCC, 0x86, - 0xCC, 0x81, 0xF6, 0x41, 0xCC, 0x86, 0xCC, 0x80, - 0xF6, 0x61, 0xCC, 0x86, 0xCC, 0x80, 0xF6, 0x41, - 0xCC, 0x86, 0xCC, 0x89, 0xF6, 0x61, 0xCC, 0x86, - 0xCC, 0x89, 0xF6, 0x41, 0xCC, 0x86, 0xCC, 0x83, - 0xF6, 0x61, 0xCC, 0x86, 0xCC, 0x83, 0xF6, 0x41, - 0xCC, 0xA3, 0xCC, 0x86, 0xF6, 0x61, 0xCC, 0xA3, - 0xCC, 0x86, 0xF6, 0x45, 0xCC, 0xA3, 0xF6, 0x65, - 0xCC, 0xA3, 0xF6, 0x45, 0xCC, 0x89, 0xF6, 0x65, - 0xCC, 0x89, 0xF6, 0x45, 0xCC, 0x83, 0xF6, 0x65, - 0xCC, 0x83, 0xF6, 0x45, 0xCC, 0x82, 0xCC, 0x81, - 0xF6, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x45, - 0xCC, 0x82, 0xCC, 0x80, 0xF6, 0x65, 0xCC, 0x82, - 0xCC, 0x80, 0xF6, 0x45, 0xCC, 0x82, 0xCC, 0x89, - 0xF6, 0x65, 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x45, - 0xCC, 0x82, 0xCC, 0x83, 0xF6, 0x65, 0xCC, 0x82, - 0xCC, 0x83, 0xF6, 0x45, 0xCC, 0xA3, 0xCC, 0x82, - 0xF6, 0x65, 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x49, - 0xCC, 0x89, 0xF6, 0x69, 0xCC, 0x89, 0xF6, 0x49, - 0xCC, 0xA3, 0xF6, 0x69, 0xCC, 0xA3, 0xF6, 0x4F, - 0xCC, 0xA3, 0xF6, 0x6F, 0xCC, 0xA3, 0xF6, 0x4F, - 0xCC, 0x89, 0xF6, 0x6F, 0xCC, 0x89, 0xF6, 0x4F, - 0xCC, 0x82, 0xCC, 0x81, 0xF6, 0x6F, 0xCC, 0x82, - 0xCC, 0x81, 0xF6, 0x4F, 0xCC, 0x82, 0xCC, 0x80, - 0xF6, 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xF6, 0x4F, - 0xCC, 0x82, 0xCC, 0x89, 0xF6, 0x6F, 0xCC, 0x82, - 0xCC, 0x89, 0xF6, 0x4F, 0xCC, 0x82, 0xCC, 0x83, - 0xF6, 0x6F, 0xCC, 0x82, 0xCC, 0x83, 0xF6, 0x4F, - 0xCC, 0xA3, 0xCC, 0x82, 0xF6, 0x6F, 0xCC, 0xA3, - 0xCC, 0x82, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0x81, - 0xF6, 0x6F, 0xCC, 0x9B, 0xCC, 0x81, 0xF6, 0x4F, - 0xCC, 0x9B, 0xCC, 0x80, 0xF6, 0x6F, 0xCC, 0x9B, - 0xCC, 0x80, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0x89, - 0xF6, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xF6, 0x4F, - 0xCC, 0x9B, 0xCC, 0x83, 0xF6, 0x6F, 0xCC, 0x9B, - 0xCC, 0x83, 0xF6, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, - 0xF6, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xF6, 0x55, - 0xCC, 0xA3, 0xF6, 0x75, 0xCC, 0xA3, 0xF6, 0x55, - 0xCC, 0x89, 0xF6, 0x75, 0xCC, 0x89, 0xF6, 0x55, - 0xCC, 0x9B, 0xCC, 0x81, 0xF6, 0x75, 0xCC, 0x9B, - 0xCC, 0x81, 0xF6, 0x55, 0xCC, 0x9B, 0xCC, 0x80, - 0xF6, 0x75, 0xCC, 0x9B, 0xCC, 0x80, 0xF6, 0x55, - 0xCC, 0x9B, 0xCC, 0x89, 0xF6, 0x75, 0xCC, 0x9B, - 0xCC, 0x89, 0xF6, 0x55, 0xCC, 0x9B, 0xCC, 0x83, - 0xF6, 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xF6, 0x55, - 0xCC, 0x9B, 0xCC, 0xA3, 0xF6, 0x75, 0xCC, 0x9B, - 0xCC, 0xA3, 0xF6, 0x59, 0xCC, 0x80, 0xF6, 0x79, - 0xCC, 0x80, 0xF6, 0x59, 0xCC, 0xA3, 0xF6, 0x79, - 0xCC, 0xA3, 0xF6, 0x59, 0xCC, 0x89, 0xF6, 0x79, - 0xCC, 0x89, 0xF6, 0x59, 0xCC, 0x83, 0xF6, 0x79, - 0xCC, 0x83, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xF6, - 0xCE, 0xB1, 0xCC, 0x94, 0xF6, 0xCE, 0xB1, 0xCC, - 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0xB1, 0xCC, 0x94, - 0xCC, 0x80, 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, - 0x81, 0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81, - 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xF6, - 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, - 0x91, 0xCC, 0x93, 0xF6, 0xCE, 0x91, 0xCC, 0x94, - 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xF6, - 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, - 0x91, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0x91, - 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCC, - 0x93, 0xCD, 0x82, 0xF6, 0xCE, 0x91, 0xCC, 0x94, - 0xCD, 0x82, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, 0xF6, - 0xCE, 0xB5, 0xCC, 0x94, 0xF6, 0xCE, 0xB5, 0xCC, - 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0xB5, 0xCC, 0x94, - 0xCC, 0x80, 0xF6, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, - 0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, - 0xF6, 0xCE, 0x95, 0xCC, 0x93, 0xF6, 0xCE, 0x95, - 0xCC, 0x94, 0xF6, 0xCE, 0x95, 0xCC, 0x93, 0xCC, - 0x80, 0xF6, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, - 0xF6, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xF6, - 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, - 0xB7, 0xCC, 0x93, 0xF6, 0xCE, 0xB7, 0xCC, 0x94, - 0xF6, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xF6, - 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, - 0xB7, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, - 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC, - 0x93, 0xCD, 0x82, 0xF6, 0xCE, 0xB7, 0xCC, 0x94, - 0xCD, 0x82, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xF6, - 0xCE, 0x97, 0xCC, 0x94, 0xF6, 0xCE, 0x97, 0xCC, - 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0x97, 0xCC, 0x94, - 0xCC, 0x80, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC, - 0x81, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81, - 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xF6, - 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, - 0xB9, 0xCC, 0x93, 0xF6, 0xCE, 0xB9, 0xCC, 0x94, - 0xF6, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xF6, - 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, - 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, - 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCC, - 0x93, 0xCD, 0x82, 0xF6, 0xCE, 0xB9, 0xCC, 0x94, - 0xCD, 0x82, 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xF6, - 0xCE, 0x99, 0xCC, 0x94, 0xF6, 0xCE, 0x99, 0xCC, - 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0x99, 0xCC, 0x94, - 0xCC, 0x80, 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xCC, - 0x81, 0xF6, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, - 0xF6, 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xF6, - 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, - 0xBF, 0xCC, 0x93, 0xF6, 0xCE, 0xBF, 0xCC, 0x94, - 0xF6, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xF6, - 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, - 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xBF, - 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, - 0x93, 0xF6, 0xCE, 0x9F, 0xCC, 0x94, 0xF6, 0xCE, - 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0x9F, - 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0x9F, 0xCC, - 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0x9F, 0xCC, 0x94, - 0xCC, 0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xF6, - 0xCF, 0x85, 0xCC, 0x94, 0xF6, 0xCF, 0x85, 0xCC, - 0x93, 0xCC, 0x80, 0xF6, 0xCF, 0x85, 0xCC, 0x94, - 0xCC, 0x80, 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xCC, - 0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, - 0xF6, 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xF6, - 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, - 0xA5, 0xCC, 0x94, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, - 0xCC, 0x80, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, - 0x81, 0xF6, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, - 0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xF6, 0xCF, 0x89, - 0xCC, 0x94, 0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xCC, - 0x80, 0xF6, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80, - 0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xF6, - 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xF6, 0xCF, - 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xF6, 0xCF, 0x89, - 0xCC, 0x94, 0xCD, 0x82, 0xF6, 0xCE, 0xA9, 0xCC, - 0x93, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xF6, 0xCE, - 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, - 0xCC, 0x94, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC, - 0x93, 0xCC, 0x81, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, - 0xCC, 0x81, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, - 0x82, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82, - 0xF6, 0xCE, 0xB1, 0xCC, 0x80, 0xF6, 0xCE, 0xB1, - 0xCC, 0x81, 0xF6, 0xCE, 0xB5, 0xCC, 0x80, 0xF6, - 0xCE, 0xB5, 0xCC, 0x81, 0xF6, 0xCE, 0xB7, 0xCC, - 0x80, 0xF6, 0xCE, 0xB7, 0xCC, 0x81, 0xF6, 0xCE, - 0xB9, 0xCC, 0x80, 0xF6, 0xCE, 0xB9, 0xCC, 0x81, - 0xF6, 0xCE, 0xBF, 0xCC, 0x80, 0xF6, 0xCE, 0xBF, - 0xCC, 0x81, 0xF6, 0xCF, 0x85, 0xCC, 0x80, 0xF6, - 0xCF, 0x85, 0xCC, 0x81, 0xF6, 0xCF, 0x89, 0xCC, - 0x80, 0xF6, 0xCF, 0x89, 0xCC, 0x81, 0xF6, 0xCE, - 0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, - 0xCC, 0x94, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC, - 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, - 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, - 0xB1, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, - 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, - 0xF6, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, - 0x85, 0xF6, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, - 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCD, - 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, - 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, - 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, - 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x93, 0xCC, - 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, 0x94, - 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x91, 0xCC, - 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x91, - 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, - 0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, - 0xCC, 0x94, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, - 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, - 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, - 0xB7, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, - 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, - 0xF6, 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCD, - 0x85, 0xF6, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82, - 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCD, - 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, - 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCD, - 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80, - 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x93, 0xCC, - 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, 0x94, - 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0x97, 0xCC, - 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x97, - 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCF, - 0x89, 0xCC, 0x93, 0xCD, 0x85, 0xF6, 0xCF, 0x89, - 0xCC, 0x94, 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC, - 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89, - 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, - 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xF6, - 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, - 0xF6, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, - 0x85, 0xF6, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82, - 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, - 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, - 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, - 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x80, - 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, - 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, 0x94, - 0xCC, 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, 0xCC, - 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0xA9, - 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, - 0xB1, 0xCC, 0x86, 0xF6, 0xCE, 0xB1, 0xCC, 0x84, - 0xF6, 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xF6, - 0xCE, 0xB1, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCC, - 0x81, 0xCD, 0x85, 0xF6, 0xCE, 0xB1, 0xCD, 0x82, - 0xF6, 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xF6, - 0xCE, 0x91, 0xCC, 0x86, 0xF6, 0xCE, 0x91, 0xCC, - 0x84, 0xF6, 0xCE, 0x91, 0xCC, 0x80, 0xF6, 0xCE, - 0x91, 0xCC, 0x81, 0xF6, 0xCE, 0x91, 0xCD, 0x85, - 0x20, 0xCC, 0x93, 0xF6, 0xCE, 0xB9, 0x20, 0xCC, - 0x93, 0x20, 0xCD, 0x82, 0xF5, 0x05, 0xC2, 0xA8, - 0xCD, 0x82, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xF6, - 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCE, - 0xB7, 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCC, 0x81, - 0xCD, 0x85, 0xF6, 0xCE, 0xB7, 0xCD, 0x82, 0xF6, - 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, - 0x95, 0xCC, 0x80, 0xF6, 0xCE, 0x95, 0xCC, 0x81, - 0xF6, 0xCE, 0x97, 0xCC, 0x80, 0xF6, 0xCE, 0x97, - 0xCC, 0x81, 0xF6, 0xCE, 0x97, 0xCD, 0x85, 0xF5, - 0x06, 0xE1, 0xBE, 0xBF, 0xCC, 0x80, 0x20, 0xCC, - 0x93, 0xCC, 0x80, 0xF5, 0x06, 0xE1, 0xBE, 0xBF, - 0xCC, 0x81, 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xF5, - 0x06, 0xE1, 0xBE, 0xBF, 0xCD, 0x82, 0x20, 0xCC, - 0x93, 0xCD, 0x82, 0xF6, 0xCE, 0xB9, 0xCC, 0x86, - 0xF6, 0xCE, 0xB9, 0xCC, 0x84, 0xF6, 0xCE, 0xB9, - 0xCC, 0x88, 0xCC, 0x80, 0xF6, 0xCE, 0xB9, 0xCC, - 0x88, 0xCC, 0x81, 0xF6, 0xCE, 0xB9, 0xCD, 0x82, - 0xF6, 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xF6, - 0xCE, 0x99, 0xCC, 0x86, 0xF6, 0xCE, 0x99, 0xCC, - 0x84, 0xF6, 0xCE, 0x99, 0xCC, 0x80, 0xF6, 0xCE, - 0x99, 0xCC, 0x81, 0xF5, 0x06, 0xE1, 0xBF, 0xBE, - 0xCC, 0x80, 0x20, 0xCC, 0x94, 0xCC, 0x80, 0xF5, - 0x06, 0xE1, 0xBF, 0xBE, 0xCC, 0x81, 0x20, 0xCC, - 0x94, 0xCC, 0x81, 0xF5, 0x06, 0xE1, 0xBF, 0xBE, - 0xCD, 0x82, 0x20, 0xCC, 0x94, 0xCD, 0x82, 0xF6, - 0xCF, 0x85, 0xCC, 0x86, 0xF6, 0xCF, 0x85, 0xCC, - 0x84, 0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, - 0xF6, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xF6, - 0xCF, 0x81, 0xCC, 0x93, 0xF6, 0xCF, 0x81, 0xCC, - 0x94, 0xF6, 0xCF, 0x85, 0xCD, 0x82, 0xF6, 0xCF, - 0x85, 0xCC, 0x88, 0xCD, 0x82, 0xF6, 0xCE, 0xA5, - 0xCC, 0x86, 0xF6, 0xCE, 0xA5, 0xCC, 0x84, 0xF6, - 0xCE, 0xA5, 0xCC, 0x80, 0xF6, 0xCE, 0xA5, 0xCC, - 0x81, 0xF6, 0xCE, 0xA1, 0xCC, 0x94, 0xF5, 0x05, - 0xC2, 0xA8, 0xCC, 0x80, 0x20, 0xCC, 0x88, 0xCC, - 0x80, 0xF5, 0x05, 0xC2, 0xA8, 0xCC, 0x81, 0x20, - 0xCC, 0x88, 0xCC, 0x81, 0xF6, 0x60, 0xF6, 0xCF, - 0x89, 0xCC, 0x80, 0xCD, 0x85, 0xF6, 0xCF, 0x89, - 0xCD, 0x85, 0xF6, 0xCF, 0x89, 0xCC, 0x81, 0xCD, - 0x85, 0xF6, 0xCF, 0x89, 0xCD, 0x82, 0xF6, 0xCF, - 0x89, 0xCD, 0x82, 0xCD, 0x85, 0xF6, 0xCE, 0x9F, - 0xCC, 0x80, 0xF6, 0xCE, 0x9F, 0xCC, 0x81, 0xF6, - 0xCE, 0xA9, 0xCC, 0x80, 0xF6, 0xCE, 0xA9, 0xCC, - 0x81, 0xF6, 0xCE, 0xA9, 0xCD, 0x85, 0xF5, 0x03, - 0xC2, 0xB4, 0x20, 0xCC, 0x81, 0x20, 0xCC, 0x94, - 0xF5, 0x04, 0xE2, 0x80, 0x82, 0x20, 0xF5, 0x04, - 0xE2, 0x80, 0x83, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0xE2, 0x80, 0x90, - 0x20, 0xCC, 0xB3, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, - 0x2E, 0x20, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, - 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, - 0xB2, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, - 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, - 0x21, 0x21, 0x20, 0xCC, 0x85, 0x3F, 0x3F, 0x3F, - 0x21, 0x21, 0x3F, 0xE2, 0x80, 0xB2, 0xE2, 0x80, - 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x20, - 0x30, 0x69, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x2B, 0xE2, 0x88, 0x92, 0x3D, 0x28, 0x29, 0x6E, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x2B, 0xE2, 0x88, 0x92, 0x3D, 0x28, - 0x29, 0x61, 0x65, 0x6F, 0x78, 0xC9, 0x99, 0x52, - 0x73, 0x61, 0x2F, 0x63, 0x61, 0x2F, 0x73, 0x43, - 0xC2, 0xB0, 0x43, 0x63, 0x2F, 0x6F, 0x63, 0x2F, - 0x75, 0xC6, 0x90, 0xC2, 0xB0, 0x46, 0x67, 0x48, - 0x48, 0x48, 0x68, 0xC4, 0xA7, 0x49, 0x49, 0x4C, - 0x6C, 0x4E, 0x4E, 0x6F, 0x50, 0x51, 0x52, 0x52, - 0x52, 0x53, 0x4D, 0x54, 0x45, 0x4C, 0x54, 0x4D, - 0x5A, 0xF6, 0xCE, 0xA9, 0x5A, 0xF6, 0x4B, 0xF6, - 0x41, 0xCC, 0x8A, 0x42, 0x43, 0x65, 0x45, 0x46, - 0x4D, 0x6F, 0xD7, 0x90, 0xD7, 0x91, 0xD7, 0x92, - 0xD7, 0x93, 0x69, 0x46, 0x41, 0x58, 0xCF, 0x80, - 0xCE, 0xB3, 0xCE, 0x93, 0xCE, 0xA0, 0xE2, 0x88, - 0x91, 0x44, 0x64, 0x65, 0x69, 0x6A, 0x31, 0xE2, - 0x81, 0x84, 0x33, 0x32, 0xE2, 0x81, 0x84, 0x33, - 0x31, 0xE2, 0x81, 0x84, 0x35, 0x32, 0xE2, 0x81, - 0x84, 0x35, 0x33, 0xE2, 0x81, 0x84, 0x35, 0x34, - 0xE2, 0x81, 0x84, 0x35, 0x31, 0xE2, 0x81, 0x84, - 0x36, 0x35, 0xE2, 0x81, 0x84, 0x36, 0x31, 0xE2, - 0x81, 0x84, 0x38, 0x33, 0xE2, 0x81, 0x84, 0x38, - 0x35, 0xE2, 0x81, 0x84, 0x38, 0x37, 0xE2, 0x81, - 0x84, 0x38, 0x31, 0xE2, 0x81, 0x84, 0x49, 0x49, - 0x49, 0x49, 0x49, 0x49, 0x49, 0x56, 0x56, 0x56, - 0x49, 0x56, 0x49, 0x49, 0x56, 0x49, 0x49, 0x49, - 0x49, 0x58, 0x58, 0x58, 0x49, 0x58, 0x49, 0x49, - 0x4C, 0x43, 0x44, 0x4D, 0x69, 0x69, 0x69, 0x69, - 0x69, 0x69, 0x69, 0x76, 0x76, 0x76, 0x69, 0x76, - 0x69, 0x69, 0x76, 0x69, 0x69, 0x69, 0x69, 0x78, - 0x78, 0x78, 0x69, 0x78, 0x69, 0x69, 0x6C, 0x63, - 0x64, 0x6D, 0xF6, 0xE2, 0x86, 0x90, 0xCC, 0xB8, - 0xF6, 0xE2, 0x86, 0x92, 0xCC, 0xB8, 0xF6, 0xE2, - 0x86, 0x94, 0xCC, 0xB8, 0xF6, 0xE2, 0x87, 0x90, - 0xCC, 0xB8, 0xF6, 0xE2, 0x87, 0x94, 0xCC, 0xB8, - 0xF6, 0xE2, 0x87, 0x92, 0xCC, 0xB8, 0xF6, 0xE2, - 0x88, 0x83, 0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0x88, - 0xCC, 0xB8, 0xF6, 0xE2, 0x88, 0x8B, 0xCC, 0xB8, - 0xF6, 0xE2, 0x88, 0xA3, 0xCC, 0xB8, 0xF6, 0xE2, - 0x88, 0xA5, 0xCC, 0xB8, 0xE2, 0x88, 0xAB, 0xE2, - 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, - 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAE, 0xE2, 0x88, - 0xAE, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xE2, - 0x88, 0xAE, 0xF6, 0xE2, 0x88, 0xBC, 0xCC, 0xB8, - 0xF6, 0xE2, 0x89, 0x83, 0xCC, 0xB8, 0xF6, 0xE2, - 0x89, 0x85, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0x88, - 0xCC, 0xB8, 0xF6, 0x3D, 0xCC, 0xB8, 0xF6, 0xE2, - 0x89, 0xA1, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0x8D, - 0xCC, 0xB8, 0xF6, 0x3C, 0xCC, 0xB8, 0xF6, 0x3E, - 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xA4, 0xCC, 0xB8, - 0xF6, 0xE2, 0x89, 0xA5, 0xCC, 0xB8, 0xF6, 0xE2, - 0x89, 0xB2, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xB3, - 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xB6, 0xCC, 0xB8, - 0xF6, 0xE2, 0x89, 0xB7, 0xCC, 0xB8, 0xF6, 0xE2, - 0x89, 0xBA, 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xBB, - 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x82, 0xCC, 0xB8, - 0xF6, 0xE2, 0x8A, 0x83, 0xCC, 0xB8, 0xF6, 0xE2, - 0x8A, 0x86, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x87, - 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xA2, 0xCC, 0xB8, - 0xF6, 0xE2, 0x8A, 0xA8, 0xCC, 0xB8, 0xF6, 0xE2, - 0x8A, 0xA9, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xAB, - 0xCC, 0xB8, 0xF6, 0xE2, 0x89, 0xBC, 0xCC, 0xB8, - 0xF6, 0xE2, 0x89, 0xBD, 0xCC, 0xB8, 0xF6, 0xE2, - 0x8A, 0x91, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0x92, - 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xB2, 0xCC, 0xB8, - 0xF6, 0xE2, 0x8A, 0xB3, 0xCC, 0xB8, 0xF6, 0xE2, - 0x8A, 0xB4, 0xCC, 0xB8, 0xF6, 0xE2, 0x8A, 0xB5, - 0xCC, 0xB8, 0xF6, 0xE3, 0x80, 0x88, 0xF6, 0xE3, - 0x80, 0x89, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x31, 0x30, 0x31, 0x31, 0x31, - 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, 0x31, - 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, 0x32, - 0x30, 0x28, 0x31, 0x29, 0x28, 0x32, 0x29, 0x28, - 0x33, 0x29, 0x28, 0x34, 0x29, 0x28, 0x35, 0x29, - 0x28, 0x36, 0x29, 0x28, 0x37, 0x29, 0x28, 0x38, - 0x29, 0x28, 0x39, 0x29, 0x28, 0x31, 0x30, 0x29, - 0x28, 0x31, 0x31, 0x29, 0x28, 0x31, 0x32, 0x29, - 0x28, 0x31, 0x33, 0x29, 0x28, 0x31, 0x34, 0x29, - 0x28, 0x31, 0x35, 0x29, 0x28, 0x31, 0x36, 0x29, - 0x28, 0x31, 0x37, 0x29, 0x28, 0x31, 0x38, 0x29, - 0x28, 0x31, 0x39, 0x29, 0x28, 0x32, 0x30, 0x29, - 0x31, 0x2E, 0x32, 0x2E, 0x33, 0x2E, 0x34, 0x2E, - 0x35, 0x2E, 0x36, 0x2E, 0x37, 0x2E, 0x38, 0x2E, - 0x39, 0x2E, 0x31, 0x30, 0x2E, 0x31, 0x31, 0x2E, - 0x31, 0x32, 0x2E, 0x31, 0x33, 0x2E, 0x31, 0x34, - 0x2E, 0x31, 0x35, 0x2E, 0x31, 0x36, 0x2E, 0x31, - 0x37, 0x2E, 0x31, 0x38, 0x2E, 0x31, 0x39, 0x2E, - 0x32, 0x30, 0x2E, 0x28, 0x61, 0x29, 0x28, 0x62, - 0x29, 0x28, 0x63, 0x29, 0x28, 0x64, 0x29, 0x28, - 0x65, 0x29, 0x28, 0x66, 0x29, 0x28, 0x67, 0x29, - 0x28, 0x68, 0x29, 0x28, 0x69, 0x29, 0x28, 0x6A, - 0x29, 0x28, 0x6B, 0x29, 0x28, 0x6C, 0x29, 0x28, - 0x6D, 0x29, 0x28, 0x6E, 0x29, 0x28, 0x6F, 0x29, - 0x28, 0x70, 0x29, 0x28, 0x71, 0x29, 0x28, 0x72, - 0x29, 0x28, 0x73, 0x29, 0x28, 0x74, 0x29, 0x28, - 0x75, 0x29, 0x28, 0x76, 0x29, 0x28, 0x77, 0x29, - 0x28, 0x78, 0x29, 0x28, 0x79, 0x29, 0x28, 0x7A, - 0x29, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0xE2, 0x88, - 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, - 0x88, 0xAB, 0x3A, 0x3A, 0x3D, 0x3D, 0x3D, 0x3D, - 0x3D, 0x3D, 0xF6, 0xE2, 0xAB, 0x9D, 0xCC, 0xB8, - 0xE2, 0xB5, 0xA1, 0xE6, 0xAF, 0x8D, 0xE9, 0xBE, - 0x9F, 0xE4, 0xB8, 0x80, 0xE4, 0xB8, 0xA8, 0xE4, - 0xB8, 0xB6, 0xE4, 0xB8, 0xBF, 0xE4, 0xB9, 0x99, - 0xE4, 0xBA, 0x85, 0xE4, 0xBA, 0x8C, 0xE4, 0xBA, - 0xA0, 0xE4, 0xBA, 0xBA, 0xE5, 0x84, 0xBF, 0xE5, - 0x85, 0xA5, 0xE5, 0x85, 0xAB, 0xE5, 0x86, 0x82, - 0xE5, 0x86, 0x96, 0xE5, 0x86, 0xAB, 0xE5, 0x87, - 0xA0, 0xE5, 0x87, 0xB5, 0xE5, 0x88, 0x80, 0xE5, - 0x8A, 0x9B, 0xE5, 0x8B, 0xB9, 0xE5, 0x8C, 0x95, - 0xE5, 0x8C, 0x9A, 0xE5, 0x8C, 0xB8, 0xE5, 0x8D, - 0x81, 0xE5, 0x8D, 0x9C, 0xE5, 0x8D, 0xA9, 0xE5, - 0x8E, 0x82, 0xE5, 0x8E, 0xB6, 0xE5, 0x8F, 0x88, - 0xE5, 0x8F, 0xA3, 0xE5, 0x9B, 0x97, 0xE5, 0x9C, - 0x9F, 0xE5, 0xA3, 0xAB, 0xE5, 0xA4, 0x82, 0xE5, - 0xA4, 0x8A, 0xE5, 0xA4, 0x95, 0xE5, 0xA4, 0xA7, - 0xE5, 0xA5, 0xB3, 0xE5, 0xAD, 0x90, 0xE5, 0xAE, - 0x80, 0xE5, 0xAF, 0xB8, 0xE5, 0xB0, 0x8F, 0xE5, - 0xB0, 0xA2, 0xE5, 0xB0, 0xB8, 0xE5, 0xB1, 0xAE, - 0xE5, 0xB1, 0xB1, 0xE5, 0xB7, 0x9B, 0xE5, 0xB7, - 0xA5, 0xE5, 0xB7, 0xB1, 0xE5, 0xB7, 0xBE, 0xE5, - 0xB9, 0xB2, 0xE5, 0xB9, 0xBA, 0xE5, 0xB9, 0xBF, - 0xE5, 0xBB, 0xB4, 0xE5, 0xBB, 0xBE, 0xE5, 0xBC, - 0x8B, 0xE5, 0xBC, 0x93, 0xE5, 0xBD, 0x90, 0xE5, - 0xBD, 0xA1, 0xE5, 0xBD, 0xB3, 0xE5, 0xBF, 0x83, - 0xE6, 0x88, 0x88, 0xE6, 0x88, 0xB6, 0xE6, 0x89, - 0x8B, 0xE6, 0x94, 0xAF, 0xE6, 0x94, 0xB4, 0xE6, - 0x96, 0x87, 0xE6, 0x96, 0x97, 0xE6, 0x96, 0xA4, - 0xE6, 0x96, 0xB9, 0xE6, 0x97, 0xA0, 0xE6, 0x97, - 0xA5, 0xE6, 0x9B, 0xB0, 0xE6, 0x9C, 0x88, 0xE6, - 0x9C, 0xA8, 0xE6, 0xAC, 0xA0, 0xE6, 0xAD, 0xA2, - 0xE6, 0xAD, 0xB9, 0xE6, 0xAE, 0xB3, 0xE6, 0xAF, - 0x8B, 0xE6, 0xAF, 0x94, 0xE6, 0xAF, 0x9B, 0xE6, - 0xB0, 0x8F, 0xE6, 0xB0, 0x94, 0xE6, 0xB0, 0xB4, - 0xE7, 0x81, 0xAB, 0xE7, 0x88, 0xAA, 0xE7, 0x88, - 0xB6, 0xE7, 0x88, 0xBB, 0xE7, 0x88, 0xBF, 0xE7, - 0x89, 0x87, 0xE7, 0x89, 0x99, 0xE7, 0x89, 0x9B, - 0xE7, 0x8A, 0xAC, 0xE7, 0x8E, 0x84, 0xE7, 0x8E, - 0x89, 0xE7, 0x93, 0x9C, 0xE7, 0x93, 0xA6, 0xE7, - 0x94, 0x98, 0xE7, 0x94, 0x9F, 0xE7, 0x94, 0xA8, - 0xE7, 0x94, 0xB0, 0xE7, 0x96, 0x8B, 0xE7, 0x96, - 0x92, 0xE7, 0x99, 0xB6, 0xE7, 0x99, 0xBD, 0xE7, - 0x9A, 0xAE, 0xE7, 0x9A, 0xBF, 0xE7, 0x9B, 0xAE, - 0xE7, 0x9F, 0x9B, 0xE7, 0x9F, 0xA2, 0xE7, 0x9F, - 0xB3, 0xE7, 0xA4, 0xBA, 0xE7, 0xA6, 0xB8, 0xE7, - 0xA6, 0xBE, 0xE7, 0xA9, 0xB4, 0xE7, 0xAB, 0x8B, - 0xE7, 0xAB, 0xB9, 0xE7, 0xB1, 0xB3, 0xE7, 0xB3, - 0xB8, 0xE7, 0xBC, 0xB6, 0xE7, 0xBD, 0x91, 0xE7, - 0xBE, 0x8A, 0xE7, 0xBE, 0xBD, 0xE8, 0x80, 0x81, - 0xE8, 0x80, 0x8C, 0xE8, 0x80, 0x92, 0xE8, 0x80, - 0xB3, 0xE8, 0x81, 0xBF, 0xE8, 0x82, 0x89, 0xE8, - 0x87, 0xA3, 0xE8, 0x87, 0xAA, 0xE8, 0x87, 0xB3, - 0xE8, 0x87, 0xBC, 0xE8, 0x88, 0x8C, 0xE8, 0x88, - 0x9B, 0xE8, 0x88, 0x9F, 0xE8, 0x89, 0xAE, 0xE8, - 0x89, 0xB2, 0xE8, 0x89, 0xB8, 0xE8, 0x99, 0x8D, - 0xE8, 0x99, 0xAB, 0xE8, 0xA1, 0x80, 0xE8, 0xA1, - 0x8C, 0xE8, 0xA1, 0xA3, 0xE8, 0xA5, 0xBE, 0xE8, - 0xA6, 0x8B, 0xE8, 0xA7, 0x92, 0xE8, 0xA8, 0x80, - 0xE8, 0xB0, 0xB7, 0xE8, 0xB1, 0x86, 0xE8, 0xB1, - 0x95, 0xE8, 0xB1, 0xB8, 0xE8, 0xB2, 0x9D, 0xE8, - 0xB5, 0xA4, 0xE8, 0xB5, 0xB0, 0xE8, 0xB6, 0xB3, - 0xE8, 0xBA, 0xAB, 0xE8, 0xBB, 0x8A, 0xE8, 0xBE, - 0x9B, 0xE8, 0xBE, 0xB0, 0xE8, 0xBE, 0xB5, 0xE9, - 0x82, 0x91, 0xE9, 0x85, 0x89, 0xE9, 0x87, 0x86, - 0xE9, 0x87, 0x8C, 0xE9, 0x87, 0x91, 0xE9, 0x95, - 0xB7, 0xE9, 0x96, 0x80, 0xE9, 0x98, 0x9C, 0xE9, - 0x9A, 0xB6, 0xE9, 0x9A, 0xB9, 0xE9, 0x9B, 0xA8, - 0xE9, 0x9D, 0x91, 0xE9, 0x9D, 0x9E, 0xE9, 0x9D, - 0xA2, 0xE9, 0x9D, 0xA9, 0xE9, 0x9F, 0x8B, 0xE9, - 0x9F, 0xAD, 0xE9, 0x9F, 0xB3, 0xE9, 0xA0, 0x81, - 0xE9, 0xA2, 0xA8, 0xE9, 0xA3, 0x9B, 0xE9, 0xA3, - 0x9F, 0xE9, 0xA6, 0x96, 0xE9, 0xA6, 0x99, 0xE9, - 0xA6, 0xAC, 0xE9, 0xAA, 0xA8, 0xE9, 0xAB, 0x98, - 0xE9, 0xAB, 0x9F, 0xE9, 0xAC, 0xA5, 0xE9, 0xAC, - 0xAF, 0xE9, 0xAC, 0xB2, 0xE9, 0xAC, 0xBC, 0xE9, - 0xAD, 0x9A, 0xE9, 0xB3, 0xA5, 0xE9, 0xB9, 0xB5, - 0xE9, 0xB9, 0xBF, 0xE9, 0xBA, 0xA5, 0xE9, 0xBA, - 0xBB, 0xE9, 0xBB, 0x83, 0xE9, 0xBB, 0x8D, 0xE9, - 0xBB, 0x91, 0xE9, 0xBB, 0xB9, 0xE9, 0xBB, 0xBD, - 0xE9, 0xBC, 0x8E, 0xE9, 0xBC, 0x93, 0xE9, 0xBC, - 0xA0, 0xE9, 0xBC, 0xBB, 0xE9, 0xBD, 0x8A, 0xE9, - 0xBD, 0x92, 0xE9, 0xBE, 0x8D, 0xE9, 0xBE, 0x9C, - 0xE9, 0xBE, 0xA0, 0x20, 0xE3, 0x80, 0x92, 0xE5, - 0x8D, 0x81, 0xE5, 0x8D, 0x84, 0xE5, 0x8D, 0x85, - 0xF6, 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x81, 0x8F, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, - 0x91, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x93, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x95, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x81, 0x97, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x81, 0x9F, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, - 0xA1, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA4, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA6, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xA8, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0xF6, - 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x81, - 0xB5, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xB5, - 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x81, 0xB8, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x81, 0xB8, 0xE3, 0x82, - 0x9A, 0xF6, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0xF6, - 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x20, 0xE3, - 0x82, 0x99, 0x20, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, - 0x82, 0x9D, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0x88, - 0xE3, 0x82, 0x8A, 0xF6, 0xE3, 0x82, 0xAB, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xAD, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x82, 0xB5, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, - 0xB7, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xB9, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBB, 0xE3, - 0x82, 0x99, 0xF6, 0xE3, 0x82, 0xBD, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x83, 0x86, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, - 0x88, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x8F, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x8F, 0xE3, - 0x82, 0x9A, 0xF6, 0xE3, 0x83, 0x92, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, - 0xF6, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, - 0x83, 0x98, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, - 0x98, 0xE3, 0x82, 0x9A, 0xF6, 0xE3, 0x83, 0x9B, - 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, 0x9B, 0xE3, - 0x82, 0x9A, 0xF6, 0xE3, 0x82, 0xA6, 0xE3, 0x82, - 0x99, 0xF6, 0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99, - 0xF6, 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0xF6, - 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0xF6, 0xE3, - 0x83, 0xB2, 0xE3, 0x82, 0x99, 0xF6, 0xE3, 0x83, - 0xBD, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xB3, 0xE3, - 0x83, 0x88, 0xE1, 0x84, 0x80, 0xE1, 0x84, 0x81, - 0xE1, 0x86, 0xAA, 0xE1, 0x84, 0x82, 0xE1, 0x86, - 0xAC, 0xE1, 0x86, 0xAD, 0xE1, 0x84, 0x83, 0xE1, - 0x84, 0x84, 0xE1, 0x84, 0x85, 0xE1, 0x86, 0xB0, - 0xE1, 0x86, 0xB1, 0xE1, 0x86, 0xB2, 0xE1, 0x86, - 0xB3, 0xE1, 0x86, 0xB4, 0xE1, 0x86, 0xB5, 0xE1, - 0x84, 0x9A, 0xE1, 0x84, 0x86, 0xE1, 0x84, 0x87, - 0xE1, 0x84, 0x88, 0xE1, 0x84, 0xA1, 0xE1, 0x84, - 0x89, 0xE1, 0x84, 0x8A, 0xE1, 0x84, 0x8B, 0xE1, - 0x84, 0x8C, 0xE1, 0x84, 0x8D, 0xE1, 0x84, 0x8E, - 0xE1, 0x84, 0x8F, 0xE1, 0x84, 0x90, 0xE1, 0x84, - 0x91, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0xE1, - 0x85, 0xA2, 0xE1, 0x85, 0xA3, 0xE1, 0x85, 0xA4, - 0xE1, 0x85, 0xA5, 0xE1, 0x85, 0xA6, 0xE1, 0x85, - 0xA7, 0xE1, 0x85, 0xA8, 0xE1, 0x85, 0xA9, 0xE1, - 0x85, 0xAA, 0xE1, 0x85, 0xAB, 0xE1, 0x85, 0xAC, - 0xE1, 0x85, 0xAD, 0xE1, 0x85, 0xAE, 0xE1, 0x85, - 0xAF, 0xE1, 0x85, 0xB0, 0xE1, 0x85, 0xB1, 0xE1, - 0x85, 0xB2, 0xE1, 0x85, 0xB3, 0xE1, 0x85, 0xB4, - 0xE1, 0x85, 0xB5, 0xE1, 0x85, 0xA0, 0xE1, 0x84, - 0x94, 0xE1, 0x84, 0x95, 0xE1, 0x87, 0x87, 0xE1, - 0x87, 0x88, 0xE1, 0x87, 0x8C, 0xE1, 0x87, 0x8E, - 0xE1, 0x87, 0x93, 0xE1, 0x87, 0x97, 0xE1, 0x87, - 0x99, 0xE1, 0x84, 0x9C, 0xE1, 0x87, 0x9D, 0xE1, - 0x87, 0x9F, 0xE1, 0x84, 0x9D, 0xE1, 0x84, 0x9E, - 0xE1, 0x84, 0xA0, 0xE1, 0x84, 0xA2, 0xE1, 0x84, - 0xA3, 0xE1, 0x84, 0xA7, 0xE1, 0x84, 0xA9, 0xE1, - 0x84, 0xAB, 0xE1, 0x84, 0xAC, 0xE1, 0x84, 0xAD, - 0xE1, 0x84, 0xAE, 0xE1, 0x84, 0xAF, 0xE1, 0x84, - 0xB2, 0xE1, 0x84, 0xB6, 0xE1, 0x85, 0x80, 0xE1, - 0x85, 0x87, 0xE1, 0x85, 0x8C, 0xE1, 0x87, 0xB1, - 0xE1, 0x87, 0xB2, 0xE1, 0x85, 0x97, 0xE1, 0x85, - 0x98, 0xE1, 0x85, 0x99, 0xE1, 0x86, 0x84, 0xE1, - 0x86, 0x85, 0xE1, 0x86, 0x88, 0xE1, 0x86, 0x91, - 0xE1, 0x86, 0x92, 0xE1, 0x86, 0x94, 0xE1, 0x86, - 0x9E, 0xE1, 0x86, 0xA1, 0xE4, 0xB8, 0x80, 0xE4, - 0xBA, 0x8C, 0xE4, 0xB8, 0x89, 0xE5, 0x9B, 0x9B, - 0xE4, 0xB8, 0x8A, 0xE4, 0xB8, 0xAD, 0xE4, 0xB8, - 0x8B, 0xE7, 0x94, 0xB2, 0xE4, 0xB9, 0x99, 0xE4, - 0xB8, 0x99, 0xE4, 0xB8, 0x81, 0xE5, 0xA4, 0xA9, - 0xE5, 0x9C, 0xB0, 0xE4, 0xBA, 0xBA, 0x28, 0xE1, - 0x84, 0x80, 0x29, 0x28, 0xE1, 0x84, 0x82, 0x29, - 0x28, 0xE1, 0x84, 0x83, 0x29, 0x28, 0xE1, 0x84, - 0x85, 0x29, 0x28, 0xE1, 0x84, 0x86, 0x29, 0x28, - 0xE1, 0x84, 0x87, 0x29, 0x28, 0xE1, 0x84, 0x89, - 0x29, 0x28, 0xE1, 0x84, 0x8B, 0x29, 0x28, 0xE1, - 0x84, 0x8C, 0x29, 0x28, 0xE1, 0x84, 0x8E, 0x29, - 0x28, 0xE1, 0x84, 0x8F, 0x29, 0x28, 0xE1, 0x84, - 0x90, 0x29, 0x28, 0xE1, 0x84, 0x91, 0x29, 0x28, - 0xE1, 0x84, 0x92, 0x29, 0x28, 0xE1, 0x84, 0x80, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x82, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x83, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x85, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x86, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x87, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x89, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8B, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8C, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8E, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8F, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x90, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x91, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x92, - 0xE1, 0x85, 0xA1, 0x29, 0x28, 0xE1, 0x84, 0x8C, - 0xE1, 0x85, 0xAE, 0x29, 0x28, 0xE1, 0x84, 0x8B, - 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, 0xE1, 0x85, - 0xA5, 0xE1, 0x86, 0xAB, 0x29, 0x28, 0xE1, 0x84, - 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x92, 0xE1, - 0x85, 0xAE, 0x29, 0x28, 0xE4, 0xB8, 0x80, 0x29, - 0x28, 0xE4, 0xBA, 0x8C, 0x29, 0x28, 0xE4, 0xB8, - 0x89, 0x29, 0x28, 0xE5, 0x9B, 0x9B, 0x29, 0x28, - 0xE4, 0xBA, 0x94, 0x29, 0x28, 0xE5, 0x85, 0xAD, - 0x29, 0x28, 0xE4, 0xB8, 0x83, 0x29, 0x28, 0xE5, - 0x85, 0xAB, 0x29, 0x28, 0xE4, 0xB9, 0x9D, 0x29, - 0x28, 0xE5, 0x8D, 0x81, 0x29, 0x28, 0xE6, 0x9C, - 0x88, 0x29, 0x28, 0xE7, 0x81, 0xAB, 0x29, 0x28, - 0xE6, 0xB0, 0xB4, 0x29, 0x28, 0xE6, 0x9C, 0xA8, - 0x29, 0x28, 0xE9, 0x87, 0x91, 0x29, 0x28, 0xE5, - 0x9C, 0x9F, 0x29, 0x28, 0xE6, 0x97, 0xA5, 0x29, - 0x28, 0xE6, 0xA0, 0xAA, 0x29, 0x28, 0xE6, 0x9C, - 0x89, 0x29, 0x28, 0xE7, 0xA4, 0xBE, 0x29, 0x28, - 0xE5, 0x90, 0x8D, 0x29, 0x28, 0xE7, 0x89, 0xB9, - 0x29, 0x28, 0xE8, 0xB2, 0xA1, 0x29, 0x28, 0xE7, - 0xA5, 0x9D, 0x29, 0x28, 0xE5, 0x8A, 0xB4, 0x29, - 0x28, 0xE4, 0xBB, 0xA3, 0x29, 0x28, 0xE5, 0x91, - 0xBC, 0x29, 0x28, 0xE5, 0xAD, 0xA6, 0x29, 0x28, - 0xE7, 0x9B, 0xA3, 0x29, 0x28, 0xE4, 0xBC, 0x81, - 0x29, 0x28, 0xE8, 0xB3, 0x87, 0x29, 0x28, 0xE5, - 0x8D, 0x94, 0x29, 0x28, 0xE7, 0xA5, 0xAD, 0x29, - 0x28, 0xE4, 0xBC, 0x91, 0x29, 0x28, 0xE8, 0x87, - 0xAA, 0x29, 0x28, 0xE8, 0x87, 0xB3, 0x29, 0x50, - 0x54, 0x45, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, - 0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, - 0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, - 0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, - 0xE1, 0x84, 0x80, 0xE1, 0x84, 0x82, 0xE1, 0x84, - 0x83, 0xE1, 0x84, 0x85, 0xE1, 0x84, 0x86, 0xE1, - 0x84, 0x87, 0xE1, 0x84, 0x89, 0xE1, 0x84, 0x8B, - 0xE1, 0x84, 0x8C, 0xE1, 0x84, 0x8E, 0xE1, 0x84, - 0x8F, 0xE1, 0x84, 0x90, 0xE1, 0x84, 0x91, 0xE1, - 0x84, 0x92, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, - 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0xE1, 0x84, - 0x83, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x85, 0xE1, - 0x85, 0xA1, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, - 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0xE1, 0x84, - 0x89, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x8B, 0xE1, - 0x85, 0xA1, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, - 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0xE1, 0x84, - 0x8F, 0xE1, 0x85, 0xA1, 0xE1, 0x84, 0x90, 0xE1, - 0x85, 0xA1, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, - 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0xE1, 0x84, - 0x8E, 0xE1, 0x85, 0xA1, 0xE1, 0x86, 0xB7, 0xE1, - 0x84, 0x80, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, - 0xE1, 0x85, 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, - 0xB4, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0xE4, - 0xB8, 0x80, 0xE4, 0xBA, 0x8C, 0xE4, 0xB8, 0x89, - 0xE5, 0x9B, 0x9B, 0xE4, 0xBA, 0x94, 0xE5, 0x85, - 0xAD, 0xE4, 0xB8, 0x83, 0xE5, 0x85, 0xAB, 0xE4, - 0xB9, 0x9D, 0xE5, 0x8D, 0x81, 0xE6, 0x9C, 0x88, - 0xE7, 0x81, 0xAB, 0xE6, 0xB0, 0xB4, 0xE6, 0x9C, - 0xA8, 0xE9, 0x87, 0x91, 0xE5, 0x9C, 0x9F, 0xE6, - 0x97, 0xA5, 0xE6, 0xA0, 0xAA, 0xE6, 0x9C, 0x89, - 0xE7, 0xA4, 0xBE, 0xE5, 0x90, 0x8D, 0xE7, 0x89, - 0xB9, 0xE8, 0xB2, 0xA1, 0xE7, 0xA5, 0x9D, 0xE5, - 0x8A, 0xB4, 0xE7, 0xA7, 0x98, 0xE7, 0x94, 0xB7, - 0xE5, 0xA5, 0xB3, 0xE9, 0x81, 0xA9, 0xE5, 0x84, - 0xAA, 0xE5, 0x8D, 0xB0, 0xE6, 0xB3, 0xA8, 0xE9, - 0xA0, 0x85, 0xE4, 0xBC, 0x91, 0xE5, 0x86, 0x99, - 0xE6, 0xAD, 0xA3, 0xE4, 0xB8, 0x8A, 0xE4, 0xB8, - 0xAD, 0xE4, 0xB8, 0x8B, 0xE5, 0xB7, 0xA6, 0xE5, - 0x8F, 0xB3, 0xE5, 0x8C, 0xBB, 0xE5, 0xAE, 0x97, - 0xE5, 0xAD, 0xA6, 0xE7, 0x9B, 0xA3, 0xE4, 0xBC, - 0x81, 0xE8, 0xB3, 0x87, 0xE5, 0x8D, 0x94, 0xE5, - 0xA4, 0x9C, 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, - 0x33, 0x39, 0x34, 0x30, 0x34, 0x31, 0x34, 0x32, - 0x34, 0x33, 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, - 0x34, 0x37, 0x34, 0x38, 0x34, 0x39, 0x35, 0x30, - 0x31, 0xE6, 0x9C, 0x88, 0x32, 0xE6, 0x9C, 0x88, - 0x33, 0xE6, 0x9C, 0x88, 0x34, 0xE6, 0x9C, 0x88, - 0x35, 0xE6, 0x9C, 0x88, 0x36, 0xE6, 0x9C, 0x88, - 0x37, 0xE6, 0x9C, 0x88, 0x38, 0xE6, 0x9C, 0x88, - 0x39, 0xE6, 0x9C, 0x88, 0x31, 0x30, 0xE6, 0x9C, - 0x88, 0x31, 0x31, 0xE6, 0x9C, 0x88, 0x31, 0x32, - 0xE6, 0x9C, 0x88, 0x48, 0x67, 0x65, 0x72, 0x67, - 0x65, 0x56, 0x4C, 0x54, 0x44, 0xE3, 0x82, 0xA2, - 0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xA6, 0xE3, 0x82, - 0xA8, 0xE3, 0x82, 0xAA, 0xE3, 0x82, 0xAB, 0xE3, - 0x82, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xB1, - 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB5, 0xE3, 0x82, - 0xB7, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xBB, 0xE3, - 0x82, 0xBD, 0xE3, 0x82, 0xBF, 0xE3, 0x83, 0x81, - 0xE3, 0x83, 0x84, 0xE3, 0x83, 0x86, 0xE3, 0x83, - 0x88, 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8B, 0xE3, - 0x83, 0x8C, 0xE3, 0x83, 0x8D, 0xE3, 0x83, 0x8E, - 0xE3, 0x83, 0x8F, 0xE3, 0x83, 0x92, 0xE3, 0x83, - 0x95, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0x9B, 0xE3, - 0x83, 0x9E, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xA0, - 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xA2, 0xE3, 0x83, - 0xA4, 0xE3, 0x83, 0xA6, 0xE3, 0x83, 0xA8, 0xE3, - 0x83, 0xA9, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xAB, - 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAD, 0xE3, 0x83, - 0xAF, 0xE3, 0x83, 0xB0, 0xE3, 0x83, 0xB1, 0xE3, - 0x83, 0xB2, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0x8F, - 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83, - 0x88, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xAB, 0xE3, - 0x83, 0x95, 0xE3, 0x82, 0xA1, 0xE3, 0x82, 0xA2, - 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82, - 0x9A, 0xE3, 0x82, 0xA2, 0xE3, 0x82, 0xA2, 0xE3, - 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xA4, - 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, - 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA4, 0xE3, - 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0xA6, - 0xE3, 0x82, 0xA9, 0xE3, 0x83, 0xB3, 0xE3, 0x82, - 0xA8, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xAF, 0xE3, - 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, - 0xE3, 0x82, 0xA8, 0xE3, 0x83, 0xBC, 0xE3, 0x82, - 0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAA, 0xE3, - 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xAA, - 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0xE3, 0x82, - 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAA, 0xE3, - 0x82, 0xAB, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, - 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xAB, 0xE3, 0x83, - 0xAD, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0xE3, - 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAD, - 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAB, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9E, 0xE3, - 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xAB, - 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xAD, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xBC, 0xE3, - 0x82, 0xAD, 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xAA, - 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAD, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBF, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAD, - 0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xAD, 0xE3, 0x83, - 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, - 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x82, 0xAD, - 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, 0xE3, 0x83, - 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0xE3, - 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAF, - 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x82, - 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, - 0x83, 0xA0, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x83, - 0x88, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF, 0xE3, - 0x83, 0xAB, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, - 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAD, 0xE3, 0x82, - 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, 0xE3, - 0x83, 0x8D, 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC, - 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xB3, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0x8A, 0xE3, 0x82, 0xB3, 0xE3, - 0x83, 0xBC, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, - 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0xA4, 0xE3, 0x82, - 0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xB5, 0xE3, - 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, 0x83, 0xBC, - 0xE3, 0x83, 0xA0, 0xE3, 0x82, 0xB7, 0xE3, 0x83, - 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF, 0xE3, - 0x82, 0x99, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, - 0xE3, 0x83, 0x81, 0xE3, 0x82, 0xBB, 0xE3, 0x83, - 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xBF, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, - 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0xE3, 0x82, - 0xB7, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, - 0x83, 0xAB, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, - 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8E, 0xE3, 0x83, - 0x8E, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, - 0x83, 0x8F, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x84, - 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, - 0xBC, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, - 0x83, 0x88, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, - 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x84, 0xE3, 0x83, - 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, - 0x83, 0xAC, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, - 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0xE3, 0x82, - 0xB9, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0xE3, - 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xAF, - 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82, - 0x9A, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x92, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, - 0xE3, 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, - 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, - 0x83, 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, 0xBC, - 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x95, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0x83, 0xE3, 0x82, 0xB7, 0xE3, - 0x82, 0xA7, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, - 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0x98, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xBF, 0xE3, - 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x98, - 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xBD, 0xE3, 0x83, - 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0x8B, 0xE3, - 0x83, 0x92, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB, - 0xE3, 0x83, 0x84, 0xE3, 0x83, 0x98, 0xE3, 0x82, - 0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0xE3, - 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, - 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0x98, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, - 0x82, 0xBF, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, - 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0x88, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0xE3, - 0x83, 0xAB, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0x9B, - 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9B, 0xE3, 0x82, - 0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, - 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x9B, 0xE3, 0x83, - 0xBC, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9E, 0xE3, - 0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, - 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83, 0xE3, - 0x83, 0x8F, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0xAB, - 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0x9E, 0xE3, 0x83, - 0xB3, 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xA7, 0xE3, - 0x83, 0xB3, 0xE3, 0x83, 0x9F, 0xE3, 0x82, 0xAF, - 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0x9F, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x9F, 0xE3, - 0x83, 0xAA, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, 0x83, - 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, - 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, - 0x83, 0xAB, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, - 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0xE3, - 0x83, 0xA6, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3, - 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x83, 0xE3, 0x83, - 0x88, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xAA, 0xE3, - 0x83, 0xA9, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, - 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x95, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xAC, - 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0xAC, 0xE3, 0x83, - 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xB1, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0xAF, - 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x30, 0xE7, - 0x82, 0xB9, 0x31, 0xE7, 0x82, 0xB9, 0x32, 0xE7, - 0x82, 0xB9, 0x33, 0xE7, 0x82, 0xB9, 0x34, 0xE7, - 0x82, 0xB9, 0x35, 0xE7, 0x82, 0xB9, 0x36, 0xE7, - 0x82, 0xB9, 0x37, 0xE7, 0x82, 0xB9, 0x38, 0xE7, - 0x82, 0xB9, 0x39, 0xE7, 0x82, 0xB9, 0x31, 0x30, - 0xE7, 0x82, 0xB9, 0x31, 0x31, 0xE7, 0x82, 0xB9, - 0x31, 0x32, 0xE7, 0x82, 0xB9, 0x31, 0x33, 0xE7, - 0x82, 0xB9, 0x31, 0x34, 0xE7, 0x82, 0xB9, 0x31, - 0x35, 0xE7, 0x82, 0xB9, 0x31, 0x36, 0xE7, 0x82, - 0xB9, 0x31, 0x37, 0xE7, 0x82, 0xB9, 0x31, 0x38, - 0xE7, 0x82, 0xB9, 0x31, 0x39, 0xE7, 0x82, 0xB9, - 0x32, 0x30, 0xE7, 0x82, 0xB9, 0x32, 0x31, 0xE7, - 0x82, 0xB9, 0x32, 0x32, 0xE7, 0x82, 0xB9, 0x32, - 0x33, 0xE7, 0x82, 0xB9, 0x32, 0x34, 0xE7, 0x82, - 0xB9, 0x68, 0x50, 0x61, 0x64, 0x61, 0x41, 0x55, - 0x62, 0x61, 0x72, 0x6F, 0x56, 0x70, 0x63, 0x64, - 0x6D, 0x64, 0x6D, 0x32, 0x64, 0x6D, 0x33, 0x49, - 0x55, 0xE5, 0xB9, 0xB3, 0xE6, 0x88, 0x90, 0xE6, - 0x98, 0xAD, 0xE5, 0x92, 0x8C, 0xE5, 0xA4, 0xA7, - 0xE6, 0xAD, 0xA3, 0xE6, 0x98, 0x8E, 0xE6, 0xB2, - 0xBB, 0xE6, 0xA0, 0xAA, 0xE5, 0xBC, 0x8F, 0xE4, - 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x70, 0x41, 0x6E, - 0x41, 0xCE, 0xBC, 0x41, 0x6D, 0x41, 0x6B, 0x41, - 0x4B, 0x42, 0x4D, 0x42, 0x47, 0x42, 0x63, 0x61, - 0x6C, 0x6B, 0x63, 0x61, 0x6C, 0x70, 0x46, 0x6E, - 0x46, 0xCE, 0xBC, 0x46, 0xCE, 0xBC, 0x67, 0x6D, - 0x67, 0x6B, 0x67, 0x48, 0x7A, 0x6B, 0x48, 0x7A, - 0x4D, 0x48, 0x7A, 0x47, 0x48, 0x7A, 0x54, 0x48, - 0x7A, 0xCE, 0xBC, 0x6C, 0x6D, 0x6C, 0x64, 0x6C, - 0x6B, 0x6C, 0x66, 0x6D, 0x6E, 0x6D, 0xCE, 0xBC, - 0x6D, 0x6D, 0x6D, 0x63, 0x6D, 0x6B, 0x6D, 0x6D, - 0x6D, 0x32, 0x63, 0x6D, 0x32, 0x6D, 0x32, 0x6B, - 0x6D, 0x32, 0x6D, 0x6D, 0x33, 0x63, 0x6D, 0x33, - 0x6D, 0x33, 0x6B, 0x6D, 0x33, 0x6D, 0xE2, 0x88, - 0x95, 0x73, 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x32, - 0x50, 0x61, 0x6B, 0x50, 0x61, 0x4D, 0x50, 0x61, - 0x47, 0x50, 0x61, 0x72, 0x61, 0x64, 0x72, 0x61, - 0x64, 0xE2, 0x88, 0x95, 0x73, 0x72, 0x61, 0x64, - 0xE2, 0x88, 0x95, 0x73, 0x32, 0x70, 0x73, 0x6E, - 0x73, 0xCE, 0xBC, 0x73, 0x6D, 0x73, 0x70, 0x56, - 0x6E, 0x56, 0xCE, 0xBC, 0x56, 0x6D, 0x56, 0x6B, - 0x56, 0x4D, 0x56, 0x70, 0x57, 0x6E, 0x57, 0xCE, - 0xBC, 0x57, 0x6D, 0x57, 0x6B, 0x57, 0x4D, 0x57, - 0x6B, 0xCE, 0xA9, 0x4D, 0xCE, 0xA9, 0x61, 0x2E, - 0x6D, 0x2E, 0x42, 0x71, 0x63, 0x63, 0x63, 0x64, - 0x43, 0xE2, 0x88, 0x95, 0x6B, 0x67, 0x43, 0x6F, - 0x2E, 0x64, 0x42, 0x47, 0x79, 0x68, 0x61, 0x48, - 0x50, 0x69, 0x6E, 0x4B, 0x4B, 0x4B, 0x4D, 0x6B, - 0x74, 0x6C, 0x6D, 0x6C, 0x6E, 0x6C, 0x6F, 0x67, - 0x6C, 0x78, 0x6D, 0x62, 0x6D, 0x69, 0x6C, 0x6D, - 0x6F, 0x6C, 0x50, 0x48, 0x70, 0x2E, 0x6D, 0x2E, - 0x50, 0x50, 0x4D, 0x50, 0x52, 0x73, 0x72, 0x53, - 0x76, 0x57, 0x62, 0x56, 0xE2, 0x88, 0x95, 0x6D, - 0x41, 0xE2, 0x88, 0x95, 0x6D, 0x31, 0xE6, 0x97, - 0xA5, 0x32, 0xE6, 0x97, 0xA5, 0x33, 0xE6, 0x97, - 0xA5, 0x34, 0xE6, 0x97, 0xA5, 0x35, 0xE6, 0x97, - 0xA5, 0x36, 0xE6, 0x97, 0xA5, 0x37, 0xE6, 0x97, - 0xA5, 0x38, 0xE6, 0x97, 0xA5, 0x39, 0xE6, 0x97, - 0xA5, 0x31, 0x30, 0xE6, 0x97, 0xA5, 0x31, 0x31, - 0xE6, 0x97, 0xA5, 0x31, 0x32, 0xE6, 0x97, 0xA5, - 0x31, 0x33, 0xE6, 0x97, 0xA5, 0x31, 0x34, 0xE6, - 0x97, 0xA5, 0x31, 0x35, 0xE6, 0x97, 0xA5, 0x31, - 0x36, 0xE6, 0x97, 0xA5, 0x31, 0x37, 0xE6, 0x97, - 0xA5, 0x31, 0x38, 0xE6, 0x97, 0xA5, 0x31, 0x39, - 0xE6, 0x97, 0xA5, 0x32, 0x30, 0xE6, 0x97, 0xA5, - 0x32, 0x31, 0xE6, 0x97, 0xA5, 0x32, 0x32, 0xE6, - 0x97, 0xA5, 0x32, 0x33, 0xE6, 0x97, 0xA5, 0x32, - 0x34, 0xE6, 0x97, 0xA5, 0x32, 0x35, 0xE6, 0x97, - 0xA5, 0x32, 0x36, 0xE6, 0x97, 0xA5, 0x32, 0x37, - 0xE6, 0x97, 0xA5, 0x32, 0x38, 0xE6, 0x97, 0xA5, - 0x32, 0x39, 0xE6, 0x97, 0xA5, 0x33, 0x30, 0xE6, - 0x97, 0xA5, 0x33, 0x31, 0xE6, 0x97, 0xA5, 0x67, - 0x61, 0x6C, 0xF6, 0xE8, 0xB1, 0x88, 0xF6, 0xE6, - 0x9B, 0xB4, 0xF6, 0xE8, 0xBB, 0x8A, 0xF6, 0xE8, - 0xB3, 0x88, 0xF6, 0xE6, 0xBB, 0x91, 0xF6, 0xE4, - 0xB8, 0xB2, 0xF6, 0xE5, 0x8F, 0xA5, 0xF6, 0xE9, - 0xBE, 0x9C, 0xF6, 0xE9, 0xBE, 0x9C, 0xF6, 0xE5, - 0xA5, 0x91, 0xF6, 0xE9, 0x87, 0x91, 0xF6, 0xE5, - 0x96, 0x87, 0xF6, 0xE5, 0xA5, 0x88, 0xF6, 0xE6, - 0x87, 0xB6, 0xF6, 0xE7, 0x99, 0xA9, 0xF6, 0xE7, - 0xBE, 0x85, 0xF6, 0xE8, 0x98, 0xBF, 0xF6, 0xE8, - 0x9E, 0xBA, 0xF6, 0xE8, 0xA3, 0xB8, 0xF6, 0xE9, - 0x82, 0x8F, 0xF6, 0xE6, 0xA8, 0x82, 0xF6, 0xE6, - 0xB4, 0x9B, 0xF6, 0xE7, 0x83, 0x99, 0xF6, 0xE7, - 0x8F, 0x9E, 0xF6, 0xE8, 0x90, 0xBD, 0xF6, 0xE9, - 0x85, 0xAA, 0xF6, 0xE9, 0xA7, 0xB1, 0xF6, 0xE4, - 0xBA, 0x82, 0xF6, 0xE5, 0x8D, 0xB5, 0xF6, 0xE6, - 0xAC, 0x84, 0xF6, 0xE7, 0x88, 0x9B, 0xF6, 0xE8, - 0x98, 0xAD, 0xF6, 0xE9, 0xB8, 0x9E, 0xF6, 0xE5, - 0xB5, 0x90, 0xF6, 0xE6, 0xBF, 0xAB, 0xF6, 0xE8, - 0x97, 0x8D, 0xF6, 0xE8, 0xA5, 0xA4, 0xF6, 0xE6, - 0x8B, 0x89, 0xF6, 0xE8, 0x87, 0x98, 0xF6, 0xE8, - 0xA0, 0x9F, 0xF6, 0xE5, 0xBB, 0x8A, 0xF6, 0xE6, - 0x9C, 0x97, 0xF6, 0xE6, 0xB5, 0xAA, 0xF6, 0xE7, - 0x8B, 0xBC, 0xF6, 0xE9, 0x83, 0x8E, 0xF6, 0xE4, - 0xBE, 0x86, 0xF6, 0xE5, 0x86, 0xB7, 0xF6, 0xE5, - 0x8B, 0x9E, 0xF6, 0xE6, 0x93, 0x84, 0xF6, 0xE6, - 0xAB, 0x93, 0xF6, 0xE7, 0x88, 0x90, 0xF6, 0xE7, - 0x9B, 0xA7, 0xF6, 0xE8, 0x80, 0x81, 0xF6, 0xE8, - 0x98, 0x86, 0xF6, 0xE8, 0x99, 0x9C, 0xF6, 0xE8, - 0xB7, 0xAF, 0xF6, 0xE9, 0x9C, 0xB2, 0xF6, 0xE9, - 0xAD, 0xAF, 0xF6, 0xE9, 0xB7, 0xBA, 0xF6, 0xE7, - 0xA2, 0x8C, 0xF6, 0xE7, 0xA5, 0xBF, 0xF6, 0xE7, - 0xB6, 0xA0, 0xF6, 0xE8, 0x8F, 0x89, 0xF6, 0xE9, - 0x8C, 0x84, 0xF6, 0xE9, 0xB9, 0xBF, 0xF6, 0xE8, - 0xAB, 0x96, 0xF6, 0xE5, 0xA3, 0x9F, 0xF6, 0xE5, - 0xBC, 0x84, 0xF6, 0xE7, 0xB1, 0xA0, 0xF6, 0xE8, - 0x81, 0xBE, 0xF6, 0xE7, 0x89, 0xA2, 0xF6, 0xE7, - 0xA3, 0x8A, 0xF6, 0xE8, 0xB3, 0x82, 0xF6, 0xE9, - 0x9B, 0xB7, 0xF6, 0xE5, 0xA3, 0x98, 0xF6, 0xE5, - 0xB1, 0xA2, 0xF6, 0xE6, 0xA8, 0x93, 0xF6, 0xE6, - 0xB7, 0x9A, 0xF6, 0xE6, 0xBC, 0x8F, 0xF6, 0xE7, - 0xB4, 0xAF, 0xF6, 0xE7, 0xB8, 0xB7, 0xF6, 0xE9, - 0x99, 0x8B, 0xF6, 0xE5, 0x8B, 0x92, 0xF6, 0xE8, - 0x82, 0x8B, 0xF6, 0xE5, 0x87, 0x9C, 0xF6, 0xE5, - 0x87, 0x8C, 0xF6, 0xE7, 0xA8, 0x9C, 0xF6, 0xE7, - 0xB6, 0xBE, 0xF6, 0xE8, 0x8F, 0xB1, 0xF6, 0xE9, - 0x99, 0xB5, 0xF6, 0xE8, 0xAE, 0x80, 0xF6, 0xE6, - 0x8B, 0x8F, 0xF6, 0xE6, 0xA8, 0x82, 0xF6, 0xE8, - 0xAB, 0xBE, 0xF6, 0xE4, 0xB8, 0xB9, 0xF6, 0xE5, - 0xAF, 0xA7, 0xF6, 0xE6, 0x80, 0x92, 0xF6, 0xE7, - 0x8E, 0x87, 0xF6, 0xE7, 0x95, 0xB0, 0xF6, 0xE5, - 0x8C, 0x97, 0xF6, 0xE7, 0xA3, 0xBB, 0xF6, 0xE4, - 0xBE, 0xBF, 0xF6, 0xE5, 0xBE, 0xA9, 0xF6, 0xE4, - 0xB8, 0x8D, 0xF6, 0xE6, 0xB3, 0x8C, 0xF6, 0xE6, - 0x95, 0xB8, 0xF6, 0xE7, 0xB4, 0xA2, 0xF6, 0xE5, - 0x8F, 0x83, 0xF6, 0xE5, 0xA1, 0x9E, 0xF6, 0xE7, - 0x9C, 0x81, 0xF6, 0xE8, 0x91, 0x89, 0xF6, 0xE8, - 0xAA, 0xAA, 0xF6, 0xE6, 0xAE, 0xBA, 0xF6, 0xE8, - 0xBE, 0xB0, 0xF6, 0xE6, 0xB2, 0x88, 0xF6, 0xE6, - 0x8B, 0xBE, 0xF6, 0xE8, 0x8B, 0xA5, 0xF6, 0xE6, - 0x8E, 0xA0, 0xF6, 0xE7, 0x95, 0xA5, 0xF6, 0xE4, - 0xBA, 0xAE, 0xF6, 0xE5, 0x85, 0xA9, 0xF6, 0xE5, - 0x87, 0x89, 0xF6, 0xE6, 0xA2, 0x81, 0xF6, 0xE7, - 0xB3, 0xA7, 0xF6, 0xE8, 0x89, 0xAF, 0xF6, 0xE8, - 0xAB, 0x92, 0xF6, 0xE9, 0x87, 0x8F, 0xF6, 0xE5, - 0x8B, 0xB5, 0xF6, 0xE5, 0x91, 0x82, 0xF6, 0xE5, - 0xA5, 0xB3, 0xF6, 0xE5, 0xBB, 0xAC, 0xF6, 0xE6, - 0x97, 0x85, 0xF6, 0xE6, 0xBF, 0xBE, 0xF6, 0xE7, - 0xA4, 0xAA, 0xF6, 0xE9, 0x96, 0xAD, 0xF6, 0xE9, - 0xA9, 0xAA, 0xF6, 0xE9, 0xBA, 0x97, 0xF6, 0xE9, - 0xBB, 0x8E, 0xF6, 0xE5, 0x8A, 0x9B, 0xF6, 0xE6, - 0x9B, 0x86, 0xF6, 0xE6, 0xAD, 0xB7, 0xF6, 0xE8, - 0xBD, 0xA2, 0xF6, 0xE5, 0xB9, 0xB4, 0xF6, 0xE6, - 0x86, 0x90, 0xF6, 0xE6, 0x88, 0x80, 0xF6, 0xE6, - 0x92, 0x9A, 0xF6, 0xE6, 0xBC, 0xA3, 0xF6, 0xE7, - 0x85, 0x89, 0xF6, 0xE7, 0x92, 0x89, 0xF6, 0xE7, - 0xA7, 0x8A, 0xF6, 0xE7, 0xB7, 0xB4, 0xF6, 0xE8, - 0x81, 0xAF, 0xF6, 0xE8, 0xBC, 0xA6, 0xF6, 0xE8, - 0x93, 0xAE, 0xF6, 0xE9, 0x80, 0xA3, 0xF6, 0xE9, - 0x8D, 0x8A, 0xF6, 0xE5, 0x88, 0x97, 0xF6, 0xE5, - 0x8A, 0xA3, 0xF6, 0xE5, 0x92, 0xBD, 0xF6, 0xE7, - 0x83, 0x88, 0xF6, 0xE8, 0xA3, 0x82, 0xF6, 0xE8, - 0xAA, 0xAA, 0xF6, 0xE5, 0xBB, 0x89, 0xF6, 0xE5, - 0xBF, 0xB5, 0xF6, 0xE6, 0x8D, 0xBB, 0xF6, 0xE6, - 0xAE, 0xAE, 0xF6, 0xE7, 0xB0, 0xBE, 0xF6, 0xE7, - 0x8D, 0xB5, 0xF6, 0xE4, 0xBB, 0xA4, 0xF6, 0xE5, - 0x9B, 0xB9, 0xF6, 0xE5, 0xAF, 0xA7, 0xF6, 0xE5, - 0xB6, 0xBA, 0xF6, 0xE6, 0x80, 0x9C, 0xF6, 0xE7, - 0x8E, 0xB2, 0xF6, 0xE7, 0x91, 0xA9, 0xF6, 0xE7, - 0xBE, 0x9A, 0xF6, 0xE8, 0x81, 0x86, 0xF6, 0xE9, - 0x88, 0xB4, 0xF6, 0xE9, 0x9B, 0xB6, 0xF6, 0xE9, - 0x9D, 0x88, 0xF6, 0xE9, 0xA0, 0x98, 0xF6, 0xE4, - 0xBE, 0x8B, 0xF6, 0xE7, 0xA6, 0xAE, 0xF6, 0xE9, - 0x86, 0xB4, 0xF6, 0xE9, 0x9A, 0xB8, 0xF6, 0xE6, - 0x83, 0xA1, 0xF6, 0xE4, 0xBA, 0x86, 0xF6, 0xE5, - 0x83, 0x9A, 0xF6, 0xE5, 0xAF, 0xAE, 0xF6, 0xE5, - 0xB0, 0xBF, 0xF6, 0xE6, 0x96, 0x99, 0xF6, 0xE6, - 0xA8, 0x82, 0xF6, 0xE7, 0x87, 0x8E, 0xF6, 0xE7, - 0x99, 0x82, 0xF6, 0xE8, 0x93, 0xBC, 0xF6, 0xE9, - 0x81, 0xBC, 0xF6, 0xE9, 0xBE, 0x8D, 0xF6, 0xE6, - 0x9A, 0x88, 0xF6, 0xE9, 0x98, 0xAE, 0xF6, 0xE5, - 0x8A, 0x89, 0xF6, 0xE6, 0x9D, 0xBB, 0xF6, 0xE6, - 0x9F, 0xB3, 0xF6, 0xE6, 0xB5, 0x81, 0xF6, 0xE6, - 0xBA, 0x9C, 0xF6, 0xE7, 0x90, 0x89, 0xF6, 0xE7, - 0x95, 0x99, 0xF6, 0xE7, 0xA1, 0xAB, 0xF6, 0xE7, - 0xB4, 0x90, 0xF6, 0xE9, 0xA1, 0x9E, 0xF6, 0xE5, - 0x85, 0xAD, 0xF6, 0xE6, 0x88, 0xAE, 0xF6, 0xE9, - 0x99, 0xB8, 0xF6, 0xE5, 0x80, 0xAB, 0xF6, 0xE5, - 0xB4, 0x99, 0xF6, 0xE6, 0xB7, 0xAA, 0xF6, 0xE8, - 0xBC, 0xAA, 0xF6, 0xE5, 0xBE, 0x8B, 0xF6, 0xE6, - 0x85, 0x84, 0xF6, 0xE6, 0xA0, 0x97, 0xF6, 0xE7, - 0x8E, 0x87, 0xF6, 0xE9, 0x9A, 0x86, 0xF6, 0xE5, - 0x88, 0xA9, 0xF6, 0xE5, 0x90, 0x8F, 0xF6, 0xE5, - 0xB1, 0xA5, 0xF6, 0xE6, 0x98, 0x93, 0xF6, 0xE6, - 0x9D, 0x8E, 0xF6, 0xE6, 0xA2, 0xA8, 0xF6, 0xE6, - 0xB3, 0xA5, 0xF6, 0xE7, 0x90, 0x86, 0xF6, 0xE7, - 0x97, 0xA2, 0xF6, 0xE7, 0xBD, 0xB9, 0xF6, 0xE8, - 0xA3, 0x8F, 0xF6, 0xE8, 0xA3, 0xA1, 0xF6, 0xE9, - 0x87, 0x8C, 0xF6, 0xE9, 0x9B, 0xA2, 0xF6, 0xE5, - 0x8C, 0xBF, 0xF6, 0xE6, 0xBA, 0xBA, 0xF6, 0xE5, - 0x90, 0x9D, 0xF6, 0xE7, 0x87, 0x90, 0xF6, 0xE7, - 0x92, 0x98, 0xF6, 0xE8, 0x97, 0xBA, 0xF6, 0xE9, - 0x9A, 0xA3, 0xF6, 0xE9, 0xB1, 0x97, 0xF6, 0xE9, - 0xBA, 0x9F, 0xF6, 0xE6, 0x9E, 0x97, 0xF6, 0xE6, - 0xB7, 0x8B, 0xF6, 0xE8, 0x87, 0xA8, 0xF6, 0xE7, - 0xAB, 0x8B, 0xF6, 0xE7, 0xAC, 0xA0, 0xF6, 0xE7, - 0xB2, 0x92, 0xF6, 0xE7, 0x8B, 0x80, 0xF6, 0xE7, - 0x82, 0x99, 0xF6, 0xE8, 0xAD, 0x98, 0xF6, 0xE4, - 0xBB, 0x80, 0xF6, 0xE8, 0x8C, 0xB6, 0xF6, 0xE5, - 0x88, 0xBA, 0xF6, 0xE5, 0x88, 0x87, 0xF6, 0xE5, - 0xBA, 0xA6, 0xF6, 0xE6, 0x8B, 0x93, 0xF6, 0xE7, - 0xB3, 0x96, 0xF6, 0xE5, 0xAE, 0x85, 0xF6, 0xE6, - 0xB4, 0x9E, 0xF6, 0xE6, 0x9A, 0xB4, 0xF6, 0xE8, - 0xBC, 0xBB, 0xF6, 0xE8, 0xA1, 0x8C, 0xF6, 0xE9, - 0x99, 0x8D, 0xF6, 0xE8, 0xA6, 0x8B, 0xF6, 0xE5, - 0xBB, 0x93, 0xF6, 0xE5, 0x85, 0x80, 0xF6, 0xE5, - 0x97, 0x80, 0xF6, 0xE5, 0xA1, 0x9A, 0xF6, 0xE6, - 0x99, 0xB4, 0xF6, 0xE5, 0x87, 0x9E, 0xF6, 0xE7, - 0x8C, 0xAA, 0xF6, 0xE7, 0x9B, 0x8A, 0xF6, 0xE7, - 0xA4, 0xBC, 0xF6, 0xE7, 0xA5, 0x9E, 0xF6, 0xE7, - 0xA5, 0xA5, 0xF6, 0xE7, 0xA6, 0x8F, 0xF6, 0xE9, - 0x9D, 0x96, 0xF6, 0xE7, 0xB2, 0xBE, 0xF6, 0xE7, - 0xBE, 0xBD, 0xF6, 0xE8, 0x98, 0x92, 0xF6, 0xE8, - 0xAB, 0xB8, 0xF6, 0xE9, 0x80, 0xB8, 0xF6, 0xE9, - 0x83, 0xBD, 0xF6, 0xE9, 0xA3, 0xAF, 0xF6, 0xE9, - 0xA3, 0xBC, 0xF6, 0xE9, 0xA4, 0xA8, 0xF6, 0xE9, - 0xB6, 0xB4, 0xF6, 0xE4, 0xBE, 0xAE, 0xF6, 0xE5, - 0x83, 0xA7, 0xF6, 0xE5, 0x85, 0x8D, 0xF6, 0xE5, - 0x8B, 0x89, 0xF6, 0xE5, 0x8B, 0xA4, 0xF6, 0xE5, - 0x8D, 0x91, 0xF6, 0xE5, 0x96, 0x9D, 0xF6, 0xE5, - 0x98, 0x86, 0xF6, 0xE5, 0x99, 0xA8, 0xF6, 0xE5, - 0xA1, 0x80, 0xF6, 0xE5, 0xA2, 0xA8, 0xF6, 0xE5, - 0xB1, 0xA4, 0xF6, 0xE5, 0xB1, 0xAE, 0xF6, 0xE6, - 0x82, 0x94, 0xF6, 0xE6, 0x85, 0xA8, 0xF6, 0xE6, - 0x86, 0x8E, 0xF6, 0xE6, 0x87, 0xB2, 0xF6, 0xE6, - 0x95, 0x8F, 0xF6, 0xE6, 0x97, 0xA2, 0xF6, 0xE6, - 0x9A, 0x91, 0xF6, 0xE6, 0xA2, 0x85, 0xF6, 0xE6, - 0xB5, 0xB7, 0xF6, 0xE6, 0xB8, 0x9A, 0xF6, 0xE6, - 0xBC, 0xA2, 0xF6, 0xE7, 0x85, 0xAE, 0xF6, 0xE7, - 0x88, 0xAB, 0xF6, 0xE7, 0x90, 0xA2, 0xF6, 0xE7, - 0xA2, 0x91, 0xF6, 0xE7, 0xA4, 0xBE, 0xF6, 0xE7, - 0xA5, 0x89, 0xF6, 0xE7, 0xA5, 0x88, 0xF6, 0xE7, - 0xA5, 0x90, 0xF6, 0xE7, 0xA5, 0x96, 0xF6, 0xE7, - 0xA5, 0x9D, 0xF6, 0xE7, 0xA6, 0x8D, 0xF6, 0xE7, - 0xA6, 0x8E, 0xF6, 0xE7, 0xA9, 0x80, 0xF6, 0xE7, - 0xAA, 0x81, 0xF6, 0xE7, 0xAF, 0x80, 0xF6, 0xE7, - 0xB7, 0xB4, 0xF6, 0xE7, 0xB8, 0x89, 0xF6, 0xE7, - 0xB9, 0x81, 0xF6, 0xE7, 0xBD, 0xB2, 0xF6, 0xE8, - 0x80, 0x85, 0xF6, 0xE8, 0x87, 0xAD, 0xF6, 0xE8, - 0x89, 0xB9, 0xF6, 0xE8, 0x89, 0xB9, 0xF6, 0xE8, - 0x91, 0x97, 0xF6, 0xE8, 0xA4, 0x90, 0xF6, 0xE8, - 0xA6, 0x96, 0xF6, 0xE8, 0xAC, 0x81, 0xF6, 0xE8, - 0xAC, 0xB9, 0xF6, 0xE8, 0xB3, 0x93, 0xF6, 0xE8, - 0xB4, 0x88, 0xF6, 0xE8, 0xBE, 0xB6, 0xF6, 0xE9, - 0x80, 0xB8, 0xF6, 0xE9, 0x9B, 0xA3, 0xF6, 0xE9, - 0x9F, 0xBF, 0xF6, 0xE9, 0xA0, 0xBB, 0xF6, 0xE4, - 0xB8, 0xA6, 0xF6, 0xE5, 0x86, 0xB5, 0xF6, 0xE5, - 0x85, 0xA8, 0xF6, 0xE4, 0xBE, 0x80, 0xF6, 0xE5, - 0x85, 0x85, 0xF6, 0xE5, 0x86, 0x80, 0xF6, 0xE5, - 0x8B, 0x87, 0xF6, 0xE5, 0x8B, 0xBA, 0xF6, 0xE5, - 0x96, 0x9D, 0xF6, 0xE5, 0x95, 0x95, 0xF6, 0xE5, - 0x96, 0x99, 0xF6, 0xE5, 0x97, 0xA2, 0xF6, 0xE5, - 0xA1, 0x9A, 0xF6, 0xE5, 0xA2, 0xB3, 0xF6, 0xE5, - 0xA5, 0x84, 0xF6, 0xE5, 0xA5, 0x94, 0xF6, 0xE5, - 0xA9, 0xA2, 0xF6, 0xE5, 0xAC, 0xA8, 0xF6, 0xE5, - 0xBB, 0x92, 0xF6, 0xE5, 0xBB, 0x99, 0xF6, 0xE5, - 0xBD, 0xA9, 0xF6, 0xE5, 0xBE, 0xAD, 0xF6, 0xE6, - 0x83, 0x98, 0xF6, 0xE6, 0x85, 0x8E, 0xF6, 0xE6, - 0x84, 0x88, 0xF6, 0xE6, 0x86, 0x8E, 0xF6, 0xE6, - 0x85, 0xA0, 0xF6, 0xE6, 0x87, 0xB2, 0xF6, 0xE6, - 0x88, 0xB4, 0xF6, 0xE6, 0x8F, 0x84, 0xF6, 0xE6, - 0x90, 0x9C, 0xF6, 0xE6, 0x91, 0x92, 0xF6, 0xE6, - 0x95, 0x96, 0xF6, 0xE6, 0x99, 0xB4, 0xF6, 0xE6, - 0x9C, 0x97, 0xF6, 0xE6, 0x9C, 0x9B, 0xF6, 0xE6, - 0x9D, 0x96, 0xF6, 0xE6, 0xAD, 0xB9, 0xF6, 0xE6, - 0xAE, 0xBA, 0xF6, 0xE6, 0xB5, 0x81, 0xF6, 0xE6, - 0xBB, 0x9B, 0xF6, 0xE6, 0xBB, 0x8B, 0xF6, 0xE6, - 0xBC, 0xA2, 0xF6, 0xE7, 0x80, 0x9E, 0xF6, 0xE7, - 0x85, 0xAE, 0xF6, 0xE7, 0x9E, 0xA7, 0xF6, 0xE7, - 0x88, 0xB5, 0xF6, 0xE7, 0x8A, 0xAF, 0xF6, 0xE7, - 0x8C, 0xAA, 0xF6, 0xE7, 0x91, 0xB1, 0xF6, 0xE7, - 0x94, 0x86, 0xF6, 0xE7, 0x94, 0xBB, 0xF6, 0xE7, - 0x98, 0x9D, 0xF6, 0xE7, 0x98, 0x9F, 0xF6, 0xE7, - 0x9B, 0x8A, 0xF6, 0xE7, 0x9B, 0x9B, 0xF6, 0xE7, - 0x9B, 0xB4, 0xF6, 0xE7, 0x9D, 0x8A, 0xF6, 0xE7, - 0x9D, 0x80, 0xF6, 0xE7, 0xA3, 0x8C, 0xF6, 0xE7, - 0xAA, 0xB1, 0xF6, 0xE7, 0xAF, 0x80, 0xF6, 0xE7, - 0xB1, 0xBB, 0xF6, 0xE7, 0xB5, 0x9B, 0xF6, 0xE7, - 0xB7, 0xB4, 0xF6, 0xE7, 0xBC, 0xBE, 0xF6, 0xE8, - 0x80, 0x85, 0xF6, 0xE8, 0x8D, 0x92, 0xF6, 0xE8, - 0x8F, 0xAF, 0xF6, 0xE8, 0x9D, 0xB9, 0xF6, 0xE8, - 0xA5, 0x81, 0xF6, 0xE8, 0xA6, 0x86, 0xF6, 0xE8, - 0xA6, 0x96, 0xF6, 0xE8, 0xAA, 0xBF, 0xF6, 0xE8, - 0xAB, 0xB8, 0xF6, 0xE8, 0xAB, 0x8B, 0xF6, 0xE8, - 0xAC, 0x81, 0xF6, 0xE8, 0xAB, 0xBE, 0xF6, 0xE8, - 0xAB, 0xAD, 0xF6, 0xE8, 0xAC, 0xB9, 0xF6, 0xE8, - 0xAE, 0x8A, 0xF6, 0xE8, 0xB4, 0x88, 0xF6, 0xE8, - 0xBC, 0xB8, 0xF6, 0xE9, 0x81, 0xB2, 0xF6, 0xE9, - 0x86, 0x99, 0xF6, 0xE9, 0x89, 0xB6, 0xF6, 0xE9, - 0x99, 0xBC, 0xF6, 0xE9, 0x9B, 0xA3, 0xF6, 0xE9, - 0x9D, 0x96, 0xF6, 0xE9, 0x9F, 0x9B, 0xF6, 0xE9, - 0x9F, 0xBF, 0xF6, 0xE9, 0xA0, 0x8B, 0xF6, 0xE9, - 0xA0, 0xBB, 0xF6, 0xE9, 0xAC, 0x92, 0xF6, 0xE9, - 0xBE, 0x9C, 0xF6, 0xF0, 0xA2, 0xA1, 0x8A, 0xF6, - 0xF0, 0xA2, 0xA1, 0x84, 0xF6, 0xF0, 0xA3, 0x8F, - 0x95, 0xF6, 0xE3, 0xAE, 0x9D, 0xF6, 0xE4, 0x80, - 0x98, 0xF6, 0xE4, 0x80, 0xB9, 0xF6, 0xF0, 0xA5, - 0x89, 0x89, 0xF6, 0xF0, 0xA5, 0xB3, 0x90, 0xF6, - 0xF0, 0xA7, 0xBB, 0x93, 0xF6, 0xE9, 0xBD, 0x83, - 0xF6, 0xE9, 0xBE, 0x8E, 0x66, 0x66, 0x66, 0x69, - 0x66, 0x6C, 0x66, 0x66, 0x69, 0x66, 0x66, 0x6C, - 0x73, 0x74, 0x73, 0x74, 0xD5, 0xB4, 0xD5, 0xB6, - 0xD5, 0xB4, 0xD5, 0xA5, 0xD5, 0xB4, 0xD5, 0xAB, - 0xD5, 0xBE, 0xD5, 0xB6, 0xD5, 0xB4, 0xD5, 0xAD, - 0xF6, 0xD7, 0x99, 0xD6, 0xB4, 0xF6, 0xD7, 0xB2, - 0xD6, 0xB7, 0xD7, 0xA2, 0xD7, 0x90, 0xD7, 0x93, - 0xD7, 0x94, 0xD7, 0x9B, 0xD7, 0x9C, 0xD7, 0x9D, - 0xD7, 0xA8, 0xD7, 0xAA, 0x2B, 0xF6, 0xD7, 0xA9, - 0xD7, 0x81, 0xF6, 0xD7, 0xA9, 0xD7, 0x82, 0xF6, - 0xD7, 0xA9, 0xD6, 0xBC, 0xD7, 0x81, 0xF6, 0xD7, - 0xA9, 0xD6, 0xBC, 0xD7, 0x82, 0xF6, 0xD7, 0x90, - 0xD6, 0xB7, 0xF6, 0xD7, 0x90, 0xD6, 0xB8, 0xF6, - 0xD7, 0x90, 0xD6, 0xBC, 0xF6, 0xD7, 0x91, 0xD6, - 0xBC, 0xF6, 0xD7, 0x92, 0xD6, 0xBC, 0xF6, 0xD7, - 0x93, 0xD6, 0xBC, 0xF6, 0xD7, 0x94, 0xD6, 0xBC, - 0xF6, 0xD7, 0x95, 0xD6, 0xBC, 0xF6, 0xD7, 0x96, - 0xD6, 0xBC, 0xF6, 0xD7, 0x98, 0xD6, 0xBC, 0xF6, - 0xD7, 0x99, 0xD6, 0xBC, 0xF6, 0xD7, 0x9A, 0xD6, - 0xBC, 0xF6, 0xD7, 0x9B, 0xD6, 0xBC, 0xF6, 0xD7, - 0x9C, 0xD6, 0xBC, 0xF6, 0xD7, 0x9E, 0xD6, 0xBC, - 0xF6, 0xD7, 0xA0, 0xD6, 0xBC, 0xF6, 0xD7, 0xA1, - 0xD6, 0xBC, 0xF6, 0xD7, 0xA3, 0xD6, 0xBC, 0xF6, - 0xD7, 0xA4, 0xD6, 0xBC, 0xF6, 0xD7, 0xA6, 0xD6, - 0xBC, 0xF6, 0xD7, 0xA7, 0xD6, 0xBC, 0xF6, 0xD7, - 0xA8, 0xD6, 0xBC, 0xF6, 0xD7, 0xA9, 0xD6, 0xBC, - 0xF6, 0xD7, 0xAA, 0xD6, 0xBC, 0xF6, 0xD7, 0x95, - 0xD6, 0xB9, 0xF6, 0xD7, 0x91, 0xD6, 0xBF, 0xF6, - 0xD7, 0x9B, 0xD6, 0xBF, 0xF6, 0xD7, 0xA4, 0xD6, - 0xBF, 0xD7, 0x90, 0xD7, 0x9C, 0xD9, 0xB1, 0xD9, - 0xB1, 0xD9, 0xBB, 0xD9, 0xBB, 0xD9, 0xBB, 0xD9, - 0xBB, 0xD9, 0xBE, 0xD9, 0xBE, 0xD9, 0xBE, 0xD9, - 0xBE, 0xDA, 0x80, 0xDA, 0x80, 0xDA, 0x80, 0xDA, - 0x80, 0xD9, 0xBA, 0xD9, 0xBA, 0xD9, 0xBA, 0xD9, - 0xBA, 0xD9, 0xBF, 0xD9, 0xBF, 0xD9, 0xBF, 0xD9, - 0xBF, 0xD9, 0xB9, 0xD9, 0xB9, 0xD9, 0xB9, 0xD9, - 0xB9, 0xDA, 0xA4, 0xDA, 0xA4, 0xDA, 0xA4, 0xDA, - 0xA4, 0xDA, 0xA6, 0xDA, 0xA6, 0xDA, 0xA6, 0xDA, - 0xA6, 0xDA, 0x84, 0xDA, 0x84, 0xDA, 0x84, 0xDA, - 0x84, 0xDA, 0x83, 0xDA, 0x83, 0xDA, 0x83, 0xDA, - 0x83, 0xDA, 0x86, 0xDA, 0x86, 0xDA, 0x86, 0xDA, - 0x86, 0xDA, 0x87, 0xDA, 0x87, 0xDA, 0x87, 0xDA, - 0x87, 0xDA, 0x8D, 0xDA, 0x8D, 0xDA, 0x8C, 0xDA, - 0x8C, 0xDA, 0x8E, 0xDA, 0x8E, 0xDA, 0x88, 0xDA, - 0x88, 0xDA, 0x98, 0xDA, 0x98, 0xDA, 0x91, 0xDA, - 0x91, 0xDA, 0xA9, 0xDA, 0xA9, 0xDA, 0xA9, 0xDA, - 0xA9, 0xDA, 0xAF, 0xDA, 0xAF, 0xDA, 0xAF, 0xDA, - 0xAF, 0xDA, 0xB3, 0xDA, 0xB3, 0xDA, 0xB3, 0xDA, - 0xB3, 0xDA, 0xB1, 0xDA, 0xB1, 0xDA, 0xB1, 0xDA, - 0xB1, 0xDA, 0xBA, 0xDA, 0xBA, 0xDA, 0xBB, 0xDA, - 0xBB, 0xDA, 0xBB, 0xDA, 0xBB, 0xDB, 0x95, 0xD9, - 0x94, 0xDB, 0x95, 0xD9, 0x94, 0xDB, 0x81, 0xDB, - 0x81, 0xDB, 0x81, 0xDB, 0x81, 0xDA, 0xBE, 0xDA, - 0xBE, 0xDA, 0xBE, 0xDA, 0xBE, 0xDB, 0x92, 0xDB, - 0x92, 0xDB, 0x92, 0xD9, 0x94, 0xDB, 0x92, 0xD9, - 0x94, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, - 0xAD, 0xDB, 0x87, 0xDB, 0x87, 0xDB, 0x86, 0xDB, - 0x86, 0xDB, 0x88, 0xDB, 0x88, 0xDB, 0x87, 0xD9, - 0xB4, 0xDB, 0x8B, 0xDB, 0x8B, 0xDB, 0x85, 0xDB, - 0x85, 0xDB, 0x89, 0xDB, 0x89, 0xDB, 0x90, 0xDB, - 0x90, 0xDB, 0x90, 0xDB, 0x90, 0xD9, 0x89, 0xD9, - 0x89, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, - 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x8A, 0xD9, - 0x94, 0xDB, 0x95, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, - 0x95, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, 0xD9, - 0x8A, 0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x8A, 0xD9, - 0x94, 0xDB, 0x87, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, - 0x87, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0xD9, - 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0xD9, 0x8A, 0xD9, - 0x94, 0xDB, 0x88, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, - 0x88, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0xD9, - 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0xD9, 0x8A, 0xD9, - 0x94, 0xDB, 0x90, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, - 0x89, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0xD9, - 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0xDB, 0x8C, 0xDB, - 0x8C, 0xDB, 0x8C, 0xDB, 0x8C, 0xD9, 0x8A, 0xD9, - 0x94, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, - 0xAD, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, - 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0xD9, 0x8A, 0xD9, - 0x94, 0xD9, 0x8A, 0xD8, 0xA8, 0xD8, 0xAC, 0xD8, - 0xA8, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xAE, 0xD8, - 0xA8, 0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x89, 0xD8, - 0xA8, 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD8, - 0xAA, 0xD8, 0xAD, 0xD8, 0xAA, 0xD8, 0xAE, 0xD8, - 0xAA, 0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x89, 0xD8, - 0xAA, 0xD9, 0x8A, 0xD8, 0xAB, 0xD8, 0xAC, 0xD8, - 0xAB, 0xD9, 0x85, 0xD8, 0xAB, 0xD9, 0x89, 0xD8, - 0xAB, 0xD9, 0x8A, 0xD8, 0xAC, 0xD8, 0xAD, 0xD8, - 0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, - 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD8, - 0xAE, 0xD8, 0xAD, 0xD8, 0xAE, 0xD9, 0x85, 0xD8, - 0xB3, 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, - 0xB3, 0xD8, 0xAE, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, - 0xB5, 0xD8, 0xAD, 0xD8, 0xB5, 0xD9, 0x85, 0xD8, - 0xB6, 0xD8, 0xAC, 0xD8, 0xB6, 0xD8, 0xAD, 0xD8, - 0xB6, 0xD8, 0xAE, 0xD8, 0xB6, 0xD9, 0x85, 0xD8, - 0xB7, 0xD8, 0xAD, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, - 0xB8, 0xD9, 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD8, - 0xB9, 0xD9, 0x85, 0xD8, 0xBA, 0xD8, 0xAC, 0xD8, - 0xBA, 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAC, 0xD9, - 0x81, 0xD8, 0xAD, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, - 0x81, 0xD9, 0x85, 0xD9, 0x81, 0xD9, 0x89, 0xD9, - 0x81, 0xD9, 0x8A, 0xD9, 0x82, 0xD8, 0xAD, 0xD9, - 0x82, 0xD9, 0x85, 0xD9, 0x82, 0xD9, 0x89, 0xD9, - 0x82, 0xD9, 0x8A, 0xD9, 0x83, 0xD8, 0xA7, 0xD9, - 0x83, 0xD8, 0xAC, 0xD9, 0x83, 0xD8, 0xAD, 0xD9, - 0x83, 0xD8, 0xAE, 0xD9, 0x83, 0xD9, 0x84, 0xD9, - 0x83, 0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x89, 0xD9, - 0x83, 0xD9, 0x8A, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, - 0x84, 0xD8, 0xAD, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, - 0x84, 0xD9, 0x85, 0xD9, 0x84, 0xD9, 0x89, 0xD9, - 0x84, 0xD9, 0x8A, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, - 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, - 0x85, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x89, 0xD9, - 0x85, 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, - 0x86, 0xD8, 0xAD, 0xD9, 0x86, 0xD8, 0xAE, 0xD9, - 0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x89, 0xD9, - 0x86, 0xD9, 0x8A, 0xD9, 0x87, 0xD8, 0xAC, 0xD9, - 0x87, 0xD9, 0x85, 0xD9, 0x87, 0xD9, 0x89, 0xD9, - 0x87, 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xAE, 0xD9, - 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x89, 0xD9, - 0x8A, 0xD9, 0x8A, 0xD8, 0xB0, 0xD9, 0xB0, 0xD8, - 0xB1, 0xD9, 0xB0, 0xD9, 0x89, 0xD9, 0xB0, 0x20, - 0xD9, 0x8C, 0xD9, 0x91, 0x20, 0xD9, 0x8D, 0xD9, - 0x91, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x20, 0xD9, - 0x8F, 0xD9, 0x91, 0x20, 0xD9, 0x90, 0xD9, 0x91, - 0x20, 0xD9, 0x91, 0xD9, 0xB0, 0xD9, 0x8A, 0xD9, - 0x94, 0xD8, 0xB1, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, - 0xB2, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, - 0x8A, 0xD9, 0x94, 0xD9, 0x86, 0xD9, 0x8A, 0xD9, - 0x94, 0xD9, 0x89, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, - 0x8A, 0xD8, 0xA8, 0xD8, 0xB1, 0xD8, 0xA8, 0xD8, - 0xB2, 0xD8, 0xA8, 0xD9, 0x85, 0xD8, 0xA8, 0xD9, - 0x86, 0xD8, 0xA8, 0xD9, 0x89, 0xD8, 0xA8, 0xD9, - 0x8A, 0xD8, 0xAA, 0xD8, 0xB1, 0xD8, 0xAA, 0xD8, - 0xB2, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAA, 0xD9, - 0x86, 0xD8, 0xAA, 0xD9, 0x89, 0xD8, 0xAA, 0xD9, - 0x8A, 0xD8, 0xAB, 0xD8, 0xB1, 0xD8, 0xAB, 0xD8, - 0xB2, 0xD8, 0xAB, 0xD9, 0x85, 0xD8, 0xAB, 0xD9, - 0x86, 0xD8, 0xAB, 0xD9, 0x89, 0xD8, 0xAB, 0xD9, - 0x8A, 0xD9, 0x81, 0xD9, 0x89, 0xD9, 0x81, 0xD9, - 0x8A, 0xD9, 0x82, 0xD9, 0x89, 0xD9, 0x82, 0xD9, - 0x8A, 0xD9, 0x83, 0xD8, 0xA7, 0xD9, 0x83, 0xD9, - 0x84, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x83, 0xD9, - 0x89, 0xD9, 0x83, 0xD9, 0x8A, 0xD9, 0x84, 0xD9, - 0x85, 0xD9, 0x84, 0xD9, 0x89, 0xD9, 0x84, 0xD9, - 0x8A, 0xD9, 0x85, 0xD8, 0xA7, 0xD9, 0x85, 0xD9, - 0x85, 0xD9, 0x86, 0xD8, 0xB1, 0xD9, 0x86, 0xD8, - 0xB2, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, - 0x86, 0xD9, 0x86, 0xD9, 0x89, 0xD9, 0x86, 0xD9, - 0x8A, 0xD9, 0x89, 0xD9, 0xB0, 0xD9, 0x8A, 0xD8, - 0xB1, 0xD9, 0x8A, 0xD8, 0xB2, 0xD9, 0x8A, 0xD9, - 0x85, 0xD9, 0x8A, 0xD9, 0x86, 0xD9, 0x8A, 0xD9, - 0x89, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, - 0x94, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, - 0xAD, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, 0xD9, - 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, - 0x94, 0xD9, 0x87, 0xD8, 0xA8, 0xD8, 0xAC, 0xD8, - 0xA8, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xAE, 0xD8, - 0xA8, 0xD9, 0x85, 0xD8, 0xA8, 0xD9, 0x87, 0xD8, - 0xAA, 0xD8, 0xAC, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, - 0xAA, 0xD8, 0xAE, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, - 0xAA, 0xD9, 0x87, 0xD8, 0xAB, 0xD9, 0x85, 0xD8, - 0xAC, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, - 0xAD, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, - 0xAE, 0xD8, 0xAC, 0xD8, 0xAE, 0xD9, 0x85, 0xD8, - 0xB3, 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, - 0xB3, 0xD8, 0xAE, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, - 0xB5, 0xD8, 0xAD, 0xD8, 0xB5, 0xD8, 0xAE, 0xD8, - 0xB5, 0xD9, 0x85, 0xD8, 0xB6, 0xD8, 0xAC, 0xD8, - 0xB6, 0xD8, 0xAD, 0xD8, 0xB6, 0xD8, 0xAE, 0xD8, - 0xB6, 0xD9, 0x85, 0xD8, 0xB7, 0xD8, 0xAD, 0xD8, - 0xB8, 0xD9, 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD8, - 0xB9, 0xD9, 0x85, 0xD8, 0xBA, 0xD8, 0xAC, 0xD8, - 0xBA, 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAC, 0xD9, - 0x81, 0xD8, 0xAD, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, - 0x81, 0xD9, 0x85, 0xD9, 0x82, 0xD8, 0xAD, 0xD9, - 0x82, 0xD9, 0x85, 0xD9, 0x83, 0xD8, 0xAC, 0xD9, - 0x83, 0xD8, 0xAD, 0xD9, 0x83, 0xD8, 0xAE, 0xD9, - 0x83, 0xD9, 0x84, 0xD9, 0x83, 0xD9, 0x85, 0xD9, - 0x84, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, - 0x84, 0xD8, 0xAE, 0xD9, 0x84, 0xD9, 0x85, 0xD9, - 0x84, 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, - 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, - 0x85, 0xD9, 0x85, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, - 0x86, 0xD8, 0xAD, 0xD9, 0x86, 0xD8, 0xAE, 0xD9, - 0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x87, 0xD9, - 0x87, 0xD8, 0xAC, 0xD9, 0x87, 0xD9, 0x85, 0xD9, - 0x87, 0xD9, 0xB0, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xAE, 0xD9, - 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x87, 0xD9, - 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, - 0x94, 0xD9, 0x87, 0xD8, 0xA8, 0xD9, 0x85, 0xD8, - 0xA8, 0xD9, 0x87, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, - 0xAA, 0xD9, 0x87, 0xD8, 0xAB, 0xD9, 0x85, 0xD8, - 0xAB, 0xD9, 0x87, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, - 0xB3, 0xD9, 0x87, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, - 0xB4, 0xD9, 0x87, 0xD9, 0x83, 0xD9, 0x84, 0xD9, - 0x83, 0xD9, 0x85, 0xD9, 0x84, 0xD9, 0x85, 0xD9, - 0x86, 0xD9, 0x85, 0xD9, 0x86, 0xD9, 0x87, 0xD9, - 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x87, 0xD9, - 0x80, 0xD9, 0x8E, 0xD9, 0x91, 0xD9, 0x80, 0xD9, - 0x8F, 0xD9, 0x91, 0xD9, 0x80, 0xD9, 0x90, 0xD9, - 0x91, 0xD8, 0xB7, 0xD9, 0x89, 0xD8, 0xB7, 0xD9, - 0x8A, 0xD8, 0xB9, 0xD9, 0x89, 0xD8, 0xB9, 0xD9, - 0x8A, 0xD8, 0xBA, 0xD9, 0x89, 0xD8, 0xBA, 0xD9, - 0x8A, 0xD8, 0xB3, 0xD9, 0x89, 0xD8, 0xB3, 0xD9, - 0x8A, 0xD8, 0xB4, 0xD9, 0x89, 0xD8, 0xB4, 0xD9, - 0x8A, 0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xAD, 0xD9, - 0x8A, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xAE, 0xD9, - 0x8A, 0xD8, 0xB5, 0xD9, 0x89, 0xD8, 0xB5, 0xD9, - 0x8A, 0xD8, 0xB6, 0xD9, 0x89, 0xD8, 0xB6, 0xD9, - 0x8A, 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, - 0xAD, 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, - 0x85, 0xD8, 0xB4, 0xD8, 0xB1, 0xD8, 0xB3, 0xD8, - 0xB1, 0xD8, 0xB5, 0xD8, 0xB1, 0xD8, 0xB6, 0xD8, - 0xB1, 0xD8, 0xB7, 0xD9, 0x89, 0xD8, 0xB7, 0xD9, - 0x8A, 0xD8, 0xB9, 0xD9, 0x89, 0xD8, 0xB9, 0xD9, - 0x8A, 0xD8, 0xBA, 0xD9, 0x89, 0xD8, 0xBA, 0xD9, - 0x8A, 0xD8, 0xB3, 0xD9, 0x89, 0xD8, 0xB3, 0xD9, - 0x8A, 0xD8, 0xB4, 0xD9, 0x89, 0xD8, 0xB4, 0xD9, - 0x8A, 0xD8, 0xAD, 0xD9, 0x89, 0xD8, 0xAD, 0xD9, - 0x8A, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD8, 0xAE, 0xD9, 0x89, 0xD8, 0xAE, 0xD9, - 0x8A, 0xD8, 0xB5, 0xD9, 0x89, 0xD8, 0xB5, 0xD9, - 0x8A, 0xD8, 0xB6, 0xD9, 0x89, 0xD8, 0xB6, 0xD9, - 0x8A, 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, - 0xAD, 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, - 0x85, 0xD8, 0xB4, 0xD8, 0xB1, 0xD8, 0xB3, 0xD8, - 0xB1, 0xD8, 0xB5, 0xD8, 0xB1, 0xD8, 0xB6, 0xD8, - 0xB1, 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, - 0xAD, 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, - 0x85, 0xD8, 0xB3, 0xD9, 0x87, 0xD8, 0xB4, 0xD9, - 0x87, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xB3, 0xD8, - 0xAC, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xB3, 0xD8, - 0xAE, 0xD8, 0xB4, 0xD8, 0xAC, 0xD8, 0xB4, 0xD8, - 0xAD, 0xD8, 0xB4, 0xD8, 0xAE, 0xD8, 0xB7, 0xD9, - 0x85, 0xD8, 0xB8, 0xD9, 0x85, 0xD8, 0xA7, 0xD9, - 0x8B, 0xD8, 0xA7, 0xD9, 0x8B, 0xD8, 0xAA, 0xD8, - 0xAC, 0xD9, 0x85, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, - 0xAC, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, - 0xAA, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAA, 0xD8, - 0xAE, 0xD9, 0x85, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, - 0xAC, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, - 0xAA, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD9, - 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, - 0xAD, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, - 0xAD, 0xD9, 0x85, 0xD9, 0x89, 0xD8, 0xB3, 0xD8, - 0xAD, 0xD8, 0xAC, 0xD8, 0xB3, 0xD8, 0xAC, 0xD8, - 0xAD, 0xD8, 0xB3, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, - 0xB3, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xB3, 0xD9, - 0x85, 0xD8, 0xAD, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, - 0xAC, 0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0xD8, - 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB5, 0xD8, - 0xAD, 0xD8, 0xAD, 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, - 0xAD, 0xD8, 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0xD8, - 0xB4, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xB4, 0xD8, - 0xAD, 0xD9, 0x85, 0xD8, 0xB4, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, - 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xB4, 0xD9, - 0x85, 0xD9, 0x85, 0xD8, 0xB4, 0xD9, 0x85, 0xD9, - 0x85, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, 0xD8, - 0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0xD8, 0xB6, 0xD8, - 0xAE, 0xD9, 0x85, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, - 0xAD, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, - 0xB7, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB7, 0xD9, - 0x85, 0xD9, 0x8A, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, - 0x85, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x85, 0xD8, - 0xB9, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB9, 0xD9, - 0x85, 0xD9, 0x89, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, - 0x85, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, - 0xBA, 0xD9, 0x85, 0xD9, 0x89, 0xD9, 0x81, 0xD8, - 0xAE, 0xD9, 0x85, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, - 0x85, 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, - 0x82, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x84, 0xD8, - 0xAD, 0xD9, 0x85, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, - 0x8A, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, 0xD9, - 0x84, 0xD8, 0xAC, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, - 0xAC, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, - 0x85, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0xD9, - 0x84, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x84, 0xD9, - 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, - 0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, - 0x85, 0xD8, 0xAD, 0xD9, 0x8A, 0xD9, 0x85, 0xD8, - 0xAC, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, - 0x85, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0xD9, - 0x85, 0xD8, 0xAE, 0xD9, 0x85, 0xD9, 0x85, 0xD8, - 0xAC, 0xD8, 0xAE, 0xD9, 0x87, 0xD9, 0x85, 0xD8, - 0xAC, 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x85, 0xD9, - 0x86, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x86, 0xD8, - 0xAD, 0xD9, 0x89, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, - 0x85, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, - 0x86, 0xD8, 0xAC, 0xD9, 0x89, 0xD9, 0x86, 0xD9, - 0x85, 0xD9, 0x8A, 0xD9, 0x86, 0xD9, 0x85, 0xD9, - 0x89, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x85, 0xD9, - 0x8A, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xA8, 0xD8, - 0xAE, 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0xD8, - 0xAA, 0xD8, 0xAE, 0xD9, 0x8A, 0xD8, 0xAA, 0xD8, - 0xAE, 0xD9, 0x89, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, - 0x8A, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0xD8, - 0xAC, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xAC, 0xD8, - 0xAD, 0xD9, 0x89, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, - 0x89, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, 0xD8, - 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, 0xD8, 0xB4, 0xD8, - 0xAD, 0xD9, 0x8A, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, - 0x8A, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, - 0x84, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, - 0xAD, 0xD9, 0x8A, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, - 0x85, 0xD9, 0x85, 0xD9, 0x8A, 0xD9, 0x82, 0xD9, - 0x85, 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, - 0x8A, 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, - 0x84, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xB9, 0xD9, - 0x85, 0xD9, 0x8A, 0xD9, 0x83, 0xD9, 0x85, 0xD9, - 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, - 0x85, 0xD8, 0xAE, 0xD9, 0x8A, 0xD9, 0x84, 0xD8, - 0xAC, 0xD9, 0x85, 0xD9, 0x83, 0xD9, 0x85, 0xD9, - 0x85, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, - 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0xD8, 0xAC, 0xD8, - 0xAD, 0xD9, 0x8A, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0xD9, - 0x81, 0xD9, 0x85, 0xD9, 0x8A, 0xD8, 0xA8, 0xD8, - 0xAD, 0xD9, 0x8A, 0xD9, 0x83, 0xD9, 0x85, 0xD9, - 0x85, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, - 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0xD8, 0xB3, 0xD8, - 0xAE, 0xD9, 0x8A, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, - 0x8A, 0xD8, 0xB5, 0xD9, 0x84, 0xDB, 0x92, 0xD9, - 0x82, 0xD9, 0x84, 0xDB, 0x92, 0xD8, 0xA7, 0xD9, - 0x84, 0xD9, 0x84, 0xD9, 0x87, 0xD8, 0xA7, 0xD9, - 0x83, 0xD8, 0xA8, 0xD8, 0xB1, 0xD9, 0x85, 0xD8, - 0xAD, 0xD9, 0x85, 0xD8, 0xAF, 0xD8, 0xB5, 0xD9, - 0x84, 0xD8, 0xB9, 0xD9, 0x85, 0xD8, 0xB1, 0xD8, - 0xB3, 0xD9, 0x88, 0xD9, 0x84, 0xD8, 0xB9, 0xD9, - 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0xD9, 0x88, 0xD8, - 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0xD8, 0xB5, 0xD9, - 0x84, 0xD9, 0x89, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, - 0x89, 0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, - 0xD9, 0x87, 0x20, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, - 0x8A, 0xD9, 0x87, 0x20, 0xD9, 0x88, 0xD8, 0xB3, - 0xD9, 0x84, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x84, - 0x20, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, - 0x84, 0xD9, 0x87, 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, - 0xA7, 0xD9, 0x84, 0x2C, 0xE3, 0x80, 0x81, 0xE3, - 0x80, 0x82, 0x3A, 0x3B, 0x21, 0x3F, 0xE3, 0x80, - 0x96, 0xE3, 0x80, 0x97, 0x2E, 0x2E, 0x2E, 0x2E, - 0x2E, 0xE2, 0x80, 0x94, 0xE2, 0x80, 0x93, 0x5F, - 0x5F, 0x28, 0x29, 0x7B, 0x7D, 0xE3, 0x80, 0x94, - 0xE3, 0x80, 0x95, 0xE3, 0x80, 0x90, 0xE3, 0x80, - 0x91, 0xE3, 0x80, 0x8A, 0xE3, 0x80, 0x8B, 0xE3, - 0x80, 0x88, 0xE3, 0x80, 0x89, 0xE3, 0x80, 0x8C, - 0xE3, 0x80, 0x8D, 0xE3, 0x80, 0x8E, 0xE3, 0x80, - 0x8F, 0x5B, 0x5D, 0x20, 0xCC, 0x85, 0x20, 0xCC, - 0x85, 0x20, 0xCC, 0x85, 0x20, 0xCC, 0x85, 0x5F, - 0x5F, 0x5F, 0x2C, 0xE3, 0x80, 0x81, 0x2E, 0x3B, - 0x3A, 0x3F, 0x21, 0xE2, 0x80, 0x94, 0x28, 0x29, - 0x7B, 0x7D, 0xE3, 0x80, 0x94, 0xE3, 0x80, 0x95, - 0x23, 0x26, 0x2A, 0x2B, 0x2D, 0x3C, 0x3E, 0x3D, - 0x5C, 0x24, 0x25, 0x40, 0x20, 0xD9, 0x8B, 0xD9, - 0x80, 0xD9, 0x8B, 0x20, 0xD9, 0x8C, 0x20, 0xD9, - 0x8D, 0x20, 0xD9, 0x8E, 0xD9, 0x80, 0xD9, 0x8E, - 0x20, 0xD9, 0x8F, 0xD9, 0x80, 0xD9, 0x8F, 0x20, - 0xD9, 0x90, 0xD9, 0x80, 0xD9, 0x90, 0x20, 0xD9, - 0x91, 0xD9, 0x80, 0xD9, 0x91, 0x20, 0xD9, 0x92, - 0xD9, 0x80, 0xD9, 0x92, 0xD8, 0xA1, 0xD8, 0xA7, - 0xD9, 0x93, 0xD8, 0xA7, 0xD9, 0x93, 0xD8, 0xA7, - 0xD9, 0x94, 0xD8, 0xA7, 0xD9, 0x94, 0xD9, 0x88, - 0xD9, 0x94, 0xD9, 0x88, 0xD9, 0x94, 0xD8, 0xA7, - 0xD9, 0x95, 0xD8, 0xA7, 0xD9, 0x95, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7, - 0xD8, 0xA7, 0xD8, 0xA8, 0xD8, 0xA8, 0xD8, 0xA8, - 0xD8, 0xA8, 0xD8, 0xA9, 0xD8, 0xA9, 0xD8, 0xAA, - 0xD8, 0xAA, 0xD8, 0xAA, 0xD8, 0xAA, 0xD8, 0xAB, - 0xD8, 0xAB, 0xD8, 0xAB, 0xD8, 0xAB, 0xD8, 0xAC, - 0xD8, 0xAC, 0xD8, 0xAC, 0xD8, 0xAC, 0xD8, 0xAD, - 0xD8, 0xAD, 0xD8, 0xAD, 0xD8, 0xAD, 0xD8, 0xAE, - 0xD8, 0xAE, 0xD8, 0xAE, 0xD8, 0xAE, 0xD8, 0xAF, - 0xD8, 0xAF, 0xD8, 0xB0, 0xD8, 0xB0, 0xD8, 0xB1, - 0xD8, 0xB1, 0xD8, 0xB2, 0xD8, 0xB2, 0xD8, 0xB3, - 0xD8, 0xB3, 0xD8, 0xB3, 0xD8, 0xB3, 0xD8, 0xB4, - 0xD8, 0xB4, 0xD8, 0xB4, 0xD8, 0xB4, 0xD8, 0xB5, - 0xD8, 0xB5, 0xD8, 0xB5, 0xD8, 0xB5, 0xD8, 0xB6, - 0xD8, 0xB6, 0xD8, 0xB6, 0xD8, 0xB6, 0xD8, 0xB7, - 0xD8, 0xB7, 0xD8, 0xB7, 0xD8, 0xB7, 0xD8, 0xB8, - 0xD8, 0xB8, 0xD8, 0xB8, 0xD8, 0xB8, 0xD8, 0xB9, - 0xD8, 0xB9, 0xD8, 0xB9, 0xD8, 0xB9, 0xD8, 0xBA, - 0xD8, 0xBA, 0xD8, 0xBA, 0xD8, 0xBA, 0xD9, 0x81, - 0xD9, 0x81, 0xD9, 0x81, 0xD9, 0x81, 0xD9, 0x82, - 0xD9, 0x82, 0xD9, 0x82, 0xD9, 0x82, 0xD9, 0x83, - 0xD9, 0x83, 0xD9, 0x83, 0xD9, 0x83, 0xD9, 0x84, - 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x85, - 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x86, - 0xD9, 0x86, 0xD9, 0x86, 0xD9, 0x86, 0xD9, 0x87, - 0xD9, 0x87, 0xD9, 0x87, 0xD9, 0x87, 0xD9, 0x88, - 0xD9, 0x88, 0xD9, 0x89, 0xD9, 0x89, 0xD9, 0x8A, - 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x8A, 0xD9, 0x84, - 0xD8, 0xA7, 0xD9, 0x93, 0xD9, 0x84, 0xD8, 0xA7, - 0xD9, 0x93, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, - 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xD9, 0x84, - 0xD8, 0xA7, 0xD9, 0x95, 0xD9, 0x84, 0xD8, 0xA7, - 0xD9, 0x95, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x84, - 0xD8, 0xA7, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, - 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, - 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, - 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, - 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, - 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, - 0xE2, 0xA6, 0x85, 0xE2, 0xA6, 0x86, 0xE3, 0x80, - 0x82, 0xE3, 0x80, 0x8C, 0xE3, 0x80, 0x8D, 0xE3, - 0x80, 0x81, 0xE3, 0x83, 0xBB, 0xE3, 0x83, 0xB2, - 0xE3, 0x82, 0xA1, 0xE3, 0x82, 0xA3, 0xE3, 0x82, - 0xA5, 0xE3, 0x82, 0xA7, 0xE3, 0x82, 0xA9, 0xE3, - 0x83, 0xA3, 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xA7, - 0xE3, 0x83, 0x83, 0xE3, 0x83, 0xBC, 0xE3, 0x82, - 0xA2, 0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xA6, 0xE3, - 0x82, 0xA8, 0xE3, 0x82, 0xAA, 0xE3, 0x82, 0xAB, - 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, - 0xB1, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB5, 0xE3, - 0x82, 0xB7, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xBB, - 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0xBF, 0xE3, 0x83, - 0x81, 0xE3, 0x83, 0x84, 0xE3, 0x83, 0x86, 0xE3, - 0x83, 0x88, 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8B, - 0xE3, 0x83, 0x8C, 0xE3, 0x83, 0x8D, 0xE3, 0x83, - 0x8E, 0xE3, 0x83, 0x8F, 0xE3, 0x83, 0x92, 0xE3, - 0x83, 0x95, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0x9B, - 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x9F, 0xE3, 0x83, - 0xA0, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xA2, 0xE3, - 0x83, 0xA4, 0xE3, 0x83, 0xA6, 0xE3, 0x83, 0xA8, - 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xAA, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAD, 0xE3, - 0x83, 0xAF, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0x99, - 0xE3, 0x82, 0x9A, 0xE1, 0x85, 0xA0, 0xE1, 0x84, - 0x80, 0xE1, 0x84, 0x81, 0xE1, 0x86, 0xAA, 0xE1, - 0x84, 0x82, 0xE1, 0x86, 0xAC, 0xE1, 0x86, 0xAD, - 0xE1, 0x84, 0x83, 0xE1, 0x84, 0x84, 0xE1, 0x84, - 0x85, 0xE1, 0x86, 0xB0, 0xE1, 0x86, 0xB1, 0xE1, - 0x86, 0xB2, 0xE1, 0x86, 0xB3, 0xE1, 0x86, 0xB4, - 0xE1, 0x86, 0xB5, 0xE1, 0x84, 0x9A, 0xE1, 0x84, - 0x86, 0xE1, 0x84, 0x87, 0xE1, 0x84, 0x88, 0xE1, - 0x84, 0xA1, 0xE1, 0x84, 0x89, 0xE1, 0x84, 0x8A, - 0xE1, 0x84, 0x8B, 0xE1, 0x84, 0x8C, 0xE1, 0x84, - 0x8D, 0xE1, 0x84, 0x8E, 0xE1, 0x84, 0x8F, 0xE1, - 0x84, 0x90, 0xE1, 0x84, 0x91, 0xE1, 0x84, 0x92, - 0xE1, 0x85, 0xA1, 0xE1, 0x85, 0xA2, 0xE1, 0x85, - 0xA3, 0xE1, 0x85, 0xA4, 0xE1, 0x85, 0xA5, 0xE1, - 0x85, 0xA6, 0xE1, 0x85, 0xA7, 0xE1, 0x85, 0xA8, - 0xE1, 0x85, 0xA9, 0xE1, 0x85, 0xAA, 0xE1, 0x85, - 0xAB, 0xE1, 0x85, 0xAC, 0xE1, 0x85, 0xAD, 0xE1, - 0x85, 0xAE, 0xE1, 0x85, 0xAF, 0xE1, 0x85, 0xB0, - 0xE1, 0x85, 0xB1, 0xE1, 0x85, 0xB2, 0xE1, 0x85, - 0xB3, 0xE1, 0x85, 0xB4, 0xE1, 0x85, 0xB5, 0xC2, - 0xA2, 0xC2, 0xA3, 0xC2, 0xAC, 0x20, 0xCC, 0x84, - 0xC2, 0xA6, 0xC2, 0xA5, 0xE2, 0x82, 0xA9, 0xE2, - 0x94, 0x82, 0xE2, 0x86, 0x90, 0xE2, 0x86, 0x91, - 0xE2, 0x86, 0x92, 0xE2, 0x86, 0x93, 0xE2, 0x96, - 0xA0, 0xE2, 0x97, 0x8B, 0xF6, 0xF0, 0x9D, 0x85, - 0x97, 0xF0, 0x9D, 0x85, 0xA5, 0xF6, 0xF0, 0x9D, - 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF6, 0xF0, - 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, - 0x9D, 0x85, 0xAE, 0xF6, 0xF0, 0x9D, 0x85, 0x98, - 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, - 0xF6, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, - 0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0xF6, 0xF0, 0x9D, - 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, - 0x85, 0xB1, 0xF6, 0xF0, 0x9D, 0x85, 0x98, 0xF0, - 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xF6, - 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, - 0xF6, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, - 0xA5, 0xF6, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, - 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xF6, 0xF0, - 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, - 0x9D, 0x85, 0xAE, 0xF6, 0xF0, 0x9D, 0x86, 0xB9, - 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, - 0xF6, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, - 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, - 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, - 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, - 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, - 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, - 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, - 0x41, 0x43, 0x44, 0x47, 0x4A, 0x4B, 0x4E, 0x4F, - 0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x66, 0x68, - 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x44, - 0x45, 0x46, 0x47, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, - 0x4F, 0x50, 0x51, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, - 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x44, 0x45, - 0x46, 0x47, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4F, - 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0xC4, 0xB1, 0xC8, 0xB7, 0xCE, 0x91, 0xCE, - 0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, - 0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, - 0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, - 0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, - 0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, - 0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2, - 0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, - 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7, - 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB, - 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF, - 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83, - 0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, - 0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE, - 0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF, - 0x81, 0xCF, 0x80, 0xCE, 0x91, 0xCE, 0x92, 0xCE, - 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, - 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, - 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, - 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE, - 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, - 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87, - 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, - 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, - 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, - 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, - 0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84, - 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88, - 0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE, - 0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF, - 0x80, 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE, - 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE, - 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE, - 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE, - 0xA0, 0xCE, 0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE, - 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE, - 0xA8, 0xCE, 0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1, - 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5, - 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9, - 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD, - 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81, - 0xCF, 0x82, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, - 0xCF, 0x86, 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, - 0xE2, 0x88, 0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, - 0xBA, 0xCF, 0x86, 0xCF, 0x81, 0xCF, 0x80, 0xCE, - 0x91, 0xCE, 0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE, - 0x95, 0xCE, 0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE, - 0x99, 0xCE, 0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, - 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, - 0xA1, 0xCE, 0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, - 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, - 0xA9, 0xE2, 0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2, - 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, - 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, - 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, - 0xCE, 0xBF, 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82, - 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86, - 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88, - 0x82, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF, - 0x86, 0xCF, 0x81, 0xCF, 0x80, 0xCE, 0x91, 0xCE, - 0x92, 0xCE, 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, - 0x96, 0xCE, 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, - 0x9A, 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, - 0x9E, 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, - 0x98, 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, - 0xA6, 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xE2, - 0x88, 0x87, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, - 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, 0xB7, - 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBB, - 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, 0xBF, - 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x82, 0xCF, 0x83, - 0xCF, 0x84, 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, - 0xCF, 0x88, 0xCF, 0x89, 0xE2, 0x88, 0x82, 0xCE, - 0xB5, 0xCE, 0xB8, 0xCE, 0xBA, 0xCF, 0x86, 0xCF, - 0x81, 0xCF, 0x80, 0xCF, 0x9C, 0xCF, 0x9D, 0x30, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, - 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0xF6, 0xE4, 0xB8, 0xBD, 0xF6, 0xE4, 0xB8, - 0xB8, 0xF6, 0xE4, 0xB9, 0x81, 0xF6, 0xF0, 0xA0, - 0x84, 0xA2, 0xF6, 0xE4, 0xBD, 0xA0, 0xF6, 0xE4, - 0xBE, 0xAE, 0xF6, 0xE4, 0xBE, 0xBB, 0xF6, 0xE5, - 0x80, 0x82, 0xF6, 0xE5, 0x81, 0xBA, 0xF6, 0xE5, - 0x82, 0x99, 0xF6, 0xE5, 0x83, 0xA7, 0xF6, 0xE5, - 0x83, 0x8F, 0xF6, 0xE3, 0x92, 0x9E, 0xF6, 0xF0, - 0xA0, 0x98, 0xBA, 0xF6, 0xE5, 0x85, 0x8D, 0xF6, - 0xE5, 0x85, 0x94, 0xF6, 0xE5, 0x85, 0xA4, 0xF6, - 0xE5, 0x85, 0xB7, 0xF6, 0xF0, 0xA0, 0x94, 0x9C, - 0xF6, 0xE3, 0x92, 0xB9, 0xF6, 0xE5, 0x85, 0xA7, - 0xF6, 0xE5, 0x86, 0x8D, 0xF6, 0xF0, 0xA0, 0x95, - 0x8B, 0xF6, 0xE5, 0x86, 0x97, 0xF6, 0xE5, 0x86, - 0xA4, 0xF6, 0xE4, 0xBB, 0x8C, 0xF6, 0xE5, 0x86, - 0xAC, 0xF6, 0xE5, 0x86, 0xB5, 0xF6, 0xF0, 0xA9, - 0x87, 0x9F, 0xF6, 0xE5, 0x87, 0xB5, 0xF6, 0xE5, - 0x88, 0x83, 0xF6, 0xE3, 0x93, 0x9F, 0xF6, 0xE5, - 0x88, 0xBB, 0xF6, 0xE5, 0x89, 0x86, 0xF6, 0xE5, - 0x89, 0xB2, 0xF6, 0xE5, 0x89, 0xB7, 0xF6, 0xE3, - 0x94, 0x95, 0xF6, 0xE5, 0x8B, 0x87, 0xF6, 0xE5, - 0x8B, 0x89, 0xF6, 0xE5, 0x8B, 0xA4, 0xF6, 0xE5, - 0x8B, 0xBA, 0xF6, 0xE5, 0x8C, 0x85, 0xF6, 0xE5, - 0x8C, 0x86, 0xF6, 0xE5, 0x8C, 0x97, 0xF6, 0xE5, - 0x8D, 0x89, 0xF6, 0xE5, 0x8D, 0x91, 0xF6, 0xE5, - 0x8D, 0x9A, 0xF6, 0xE5, 0x8D, 0xB3, 0xF6, 0xE5, - 0x8D, 0xBD, 0xF6, 0xE5, 0x8D, 0xBF, 0xF6, 0xE5, - 0x8D, 0xBF, 0xF6, 0xE5, 0x8D, 0xBF, 0xF6, 0xF0, - 0xA0, 0xA8, 0xAC, 0xF6, 0xE7, 0x81, 0xB0, 0xF6, - 0xE5, 0x8F, 0x8A, 0xF6, 0xE5, 0x8F, 0x9F, 0xF6, - 0xF0, 0xA0, 0xAD, 0xA3, 0xF6, 0xE5, 0x8F, 0xAB, - 0xF6, 0xE5, 0x8F, 0xB1, 0xF6, 0xE5, 0x90, 0x86, - 0xF6, 0xE5, 0x92, 0x9E, 0xF6, 0xE5, 0x90, 0xB8, - 0xF6, 0xE5, 0x91, 0x88, 0xF6, 0xE5, 0x91, 0xA8, - 0xF6, 0xE5, 0x92, 0xA2, 0xF6, 0xE5, 0x93, 0xB6, - 0xF6, 0xE5, 0x94, 0x90, 0xF6, 0xE5, 0x95, 0x93, - 0xF6, 0xE5, 0x95, 0xA3, 0xF6, 0xE5, 0x96, 0x84, - 0xF6, 0xE5, 0x96, 0x84, 0xF6, 0xE5, 0x96, 0x99, - 0xF6, 0xE5, 0x96, 0xAB, 0xF6, 0xE5, 0x96, 0xB3, - 0xF6, 0xE5, 0x97, 0x82, 0xF6, 0xE5, 0x9C, 0x96, - 0xF6, 0xE5, 0x98, 0x86, 0xF6, 0xE5, 0x9C, 0x97, - 0xF6, 0xE5, 0x99, 0x91, 0xF6, 0xE5, 0x99, 0xB4, - 0xF6, 0xE5, 0x88, 0x87, 0xF6, 0xE5, 0xA3, 0xAE, - 0xF6, 0xE5, 0x9F, 0x8E, 0xF6, 0xE5, 0x9F, 0xB4, - 0xF6, 0xE5, 0xA0, 0x8D, 0xF6, 0xE5, 0x9E, 0x8B, - 0xF6, 0xE5, 0xA0, 0xB2, 0xF6, 0xE5, 0xA0, 0xB1, - 0xF6, 0xE5, 0xA2, 0xAC, 0xF6, 0xF0, 0xA1, 0x93, - 0xA4, 0xF6, 0xE5, 0xA3, 0xB2, 0xF6, 0xE5, 0xA3, - 0xB7, 0xF6, 0xE5, 0xA4, 0x86, 0xF6, 0xE5, 0xA4, - 0x9A, 0xF6, 0xE5, 0xA4, 0xA2, 0xF6, 0xE5, 0xA5, - 0xA2, 0xF6, 0xF0, 0xA1, 0x9A, 0xA8, 0xF6, 0xF0, - 0xA1, 0x9B, 0xAA, 0xF6, 0xE5, 0xA7, 0xAC, 0xF6, - 0xE5, 0xA8, 0x9B, 0xF6, 0xE5, 0xA8, 0xA7, 0xF6, - 0xE5, 0xA7, 0x98, 0xF6, 0xE5, 0xA9, 0xA6, 0xF6, - 0xE3, 0x9B, 0xAE, 0xF6, 0xE3, 0x9B, 0xBC, 0xF6, - 0xE5, 0xAC, 0x88, 0xF6, 0xE5, 0xAC, 0xBE, 0xF6, - 0xE5, 0xAC, 0xBE, 0xF6, 0xF0, 0xA1, 0xA7, 0x88, - 0xF6, 0xE5, 0xAF, 0x83, 0xF6, 0xE5, 0xAF, 0x98, - 0xF6, 0xE5, 0xAF, 0xA7, 0xF6, 0xE5, 0xAF, 0xB3, - 0xF6, 0xF0, 0xA1, 0xAC, 0x98, 0xF6, 0xE5, 0xAF, - 0xBF, 0xF6, 0xE5, 0xB0, 0x86, 0xF6, 0xE5, 0xBD, - 0x93, 0xF6, 0xE5, 0xB0, 0xA2, 0xF6, 0xE3, 0x9E, - 0x81, 0xF6, 0xE5, 0xB1, 0xA0, 0xF6, 0xE5, 0xB1, - 0xAE, 0xF6, 0xE5, 0xB3, 0x80, 0xF6, 0xE5, 0xB2, - 0x8D, 0xF6, 0xF0, 0xA1, 0xB7, 0xA4, 0xF6, 0xE5, - 0xB5, 0x83, 0xF6, 0xF0, 0xA1, 0xB7, 0xA6, 0xF6, - 0xE5, 0xB5, 0xAE, 0xF6, 0xE5, 0xB5, 0xAB, 0xF6, - 0xE5, 0xB5, 0xBC, 0xF6, 0xE5, 0xB7, 0xA1, 0xF6, - 0xE5, 0xB7, 0xA2, 0xF6, 0xE3, 0xA0, 0xAF, 0xF6, - 0xE5, 0xB7, 0xBD, 0xF6, 0xE5, 0xB8, 0xA8, 0xF6, - 0xE5, 0xB8, 0xBD, 0xF6, 0xE5, 0xB9, 0xA9, 0xF6, - 0xE3, 0xA1, 0xA2, 0xF6, 0xF0, 0xA2, 0x86, 0x83, - 0xF6, 0xE3, 0xA1, 0xBC, 0xF6, 0xE5, 0xBA, 0xB0, - 0xF6, 0xE5, 0xBA, 0xB3, 0xF6, 0xE5, 0xBA, 0xB6, - 0xF6, 0xE5, 0xBB, 0x8A, 0xF6, 0xF0, 0xAA, 0x8E, - 0x92, 0xF6, 0xE5, 0xBB, 0xBE, 0xF6, 0xF0, 0xA2, - 0x8C, 0xB1, 0xF6, 0xF0, 0xA2, 0x8C, 0xB1, 0xF6, - 0xE8, 0x88, 0x81, 0xF6, 0xE5, 0xBC, 0xA2, 0xF6, - 0xE5, 0xBC, 0xA2, 0xF6, 0xE3, 0xA3, 0x87, 0xF6, - 0xF0, 0xA3, 0x8A, 0xB8, 0xF6, 0xF0, 0xA6, 0x87, - 0x9A, 0xF6, 0xE5, 0xBD, 0xA2, 0xF6, 0xE5, 0xBD, - 0xAB, 0xF6, 0xE3, 0xA3, 0xA3, 0xF6, 0xE5, 0xBE, - 0x9A, 0xF6, 0xE5, 0xBF, 0x8D, 0xF6, 0xE5, 0xBF, - 0x97, 0xF6, 0xE5, 0xBF, 0xB9, 0xF6, 0xE6, 0x82, - 0x81, 0xF6, 0xE3, 0xA4, 0xBA, 0xF6, 0xE3, 0xA4, - 0x9C, 0xF6, 0xE6, 0x82, 0x94, 0xF6, 0xF0, 0xA2, - 0x9B, 0x94, 0xF6, 0xE6, 0x83, 0x87, 0xF6, 0xE6, - 0x85, 0x88, 0xF6, 0xE6, 0x85, 0x8C, 0xF6, 0xE6, - 0x85, 0x8E, 0xF6, 0xE6, 0x85, 0x8C, 0xF6, 0xE6, - 0x85, 0xBA, 0xF6, 0xE6, 0x86, 0x8E, 0xF6, 0xE6, - 0x86, 0xB2, 0xF6, 0xE6, 0x86, 0xA4, 0xF6, 0xE6, - 0x86, 0xAF, 0xF6, 0xE6, 0x87, 0x9E, 0xF6, 0xE6, - 0x87, 0xB2, 0xF6, 0xE6, 0x87, 0xB6, 0xF6, 0xE6, - 0x88, 0x90, 0xF6, 0xE6, 0x88, 0x9B, 0xF6, 0xE6, - 0x89, 0x9D, 0xF6, 0xE6, 0x8A, 0xB1, 0xF6, 0xE6, - 0x8B, 0x94, 0xF6, 0xE6, 0x8D, 0x90, 0xF6, 0xF0, - 0xA2, 0xAC, 0x8C, 0xF6, 0xE6, 0x8C, 0xBD, 0xF6, - 0xE6, 0x8B, 0xBC, 0xF6, 0xE6, 0x8D, 0xA8, 0xF6, - 0xE6, 0x8E, 0x83, 0xF6, 0xE6, 0x8F, 0xA4, 0xF6, - 0xF0, 0xA2, 0xAF, 0xB1, 0xF6, 0xE6, 0x90, 0xA2, - 0xF6, 0xE6, 0x8F, 0x85, 0xF6, 0xE6, 0x8E, 0xA9, - 0xF6, 0xE3, 0xA8, 0xAE, 0xF6, 0xE6, 0x91, 0xA9, - 0xF6, 0xE6, 0x91, 0xBE, 0xF6, 0xE6, 0x92, 0x9D, - 0xF6, 0xE6, 0x91, 0xB7, 0xF6, 0xE3, 0xA9, 0xAC, - 0xF6, 0xE6, 0x95, 0x8F, 0xF6, 0xE6, 0x95, 0xAC, - 0xF6, 0xF0, 0xA3, 0x80, 0x8A, 0xF6, 0xE6, 0x97, - 0xA3, 0xF6, 0xE6, 0x9B, 0xB8, 0xF6, 0xE6, 0x99, - 0x89, 0xF6, 0xE3, 0xAC, 0x99, 0xF6, 0xE6, 0x9A, - 0x91, 0xF6, 0xE3, 0xAC, 0x88, 0xF6, 0xE3, 0xAB, - 0xA4, 0xF6, 0xE5, 0x86, 0x92, 0xF6, 0xE5, 0x86, - 0x95, 0xF6, 0xE6, 0x9C, 0x80, 0xF6, 0xE6, 0x9A, - 0x9C, 0xF6, 0xE8, 0x82, 0xAD, 0xF6, 0xE4, 0x8F, - 0x99, 0xF6, 0xE6, 0x9C, 0x97, 0xF6, 0xE6, 0x9C, - 0x9B, 0xF6, 0xE6, 0x9C, 0xA1, 0xF6, 0xE6, 0x9D, - 0x9E, 0xF6, 0xE6, 0x9D, 0x93, 0xF6, 0xF0, 0xA3, - 0x8F, 0x83, 0xF6, 0xE3, 0xAD, 0x89, 0xF6, 0xE6, - 0x9F, 0xBA, 0xF6, 0xE6, 0x9E, 0x85, 0xF6, 0xE6, - 0xA1, 0x92, 0xF6, 0xE6, 0xA2, 0x85, 0xF6, 0xF0, - 0xA3, 0x91, 0xAD, 0xF6, 0xE6, 0xA2, 0x8E, 0xF6, - 0xE6, 0xA0, 0x9F, 0xF6, 0xE6, 0xA4, 0x94, 0xF6, - 0xE3, 0xAE, 0x9D, 0xF6, 0xE6, 0xA5, 0x82, 0xF6, - 0xE6, 0xA6, 0xA3, 0xF6, 0xE6, 0xA7, 0xAA, 0xF6, - 0xE6, 0xAA, 0xA8, 0xF6, 0xF0, 0xA3, 0x9A, 0xA3, - 0xF6, 0xE6, 0xAB, 0x9B, 0xF6, 0xE3, 0xB0, 0x98, - 0xF6, 0xE6, 0xAC, 0xA1, 0xF6, 0xF0, 0xA3, 0xA2, - 0xA7, 0xF6, 0xE6, 0xAD, 0x94, 0xF6, 0xE3, 0xB1, - 0x8E, 0xF6, 0xE6, 0xAD, 0xB2, 0xF6, 0xE6, 0xAE, - 0x9F, 0xF6, 0xE6, 0xAE, 0xBA, 0xF6, 0xE6, 0xAE, - 0xBB, 0xF6, 0xF0, 0xA3, 0xAA, 0x8D, 0xF6, 0xF0, - 0xA1, 0xB4, 0x8B, 0xF6, 0xF0, 0xA3, 0xAB, 0xBA, - 0xF6, 0xE6, 0xB1, 0x8E, 0xF6, 0xF0, 0xA3, 0xB2, - 0xBC, 0xF6, 0xE6, 0xB2, 0xBF, 0xF6, 0xE6, 0xB3, - 0x8D, 0xF6, 0xE6, 0xB1, 0xA7, 0xF6, 0xE6, 0xB4, - 0x96, 0xF6, 0xE6, 0xB4, 0xBE, 0xF6, 0xE6, 0xB5, - 0xB7, 0xF6, 0xE6, 0xB5, 0x81, 0xF6, 0xE6, 0xB5, - 0xA9, 0xF6, 0xE6, 0xB5, 0xB8, 0xF6, 0xE6, 0xB6, - 0x85, 0xF6, 0xF0, 0xA3, 0xB4, 0x9E, 0xF6, 0xE6, - 0xB4, 0xB4, 0xF6, 0xE6, 0xB8, 0xAF, 0xF6, 0xE6, - 0xB9, 0xAE, 0xF6, 0xE3, 0xB4, 0xB3, 0xF6, 0xE6, - 0xBB, 0x8B, 0xF6, 0xE6, 0xBB, 0x87, 0xF6, 0xF0, - 0xA3, 0xBB, 0x91, 0xF6, 0xE6, 0xB7, 0xB9, 0xF6, - 0xE6, 0xBD, 0xAE, 0xF6, 0xF0, 0xA3, 0xBD, 0x9E, - 0xF6, 0xF0, 0xA3, 0xBE, 0x8E, 0xF6, 0xE6, 0xBF, - 0x86, 0xF6, 0xE7, 0x80, 0xB9, 0xF6, 0xE7, 0x80, - 0x9E, 0xF6, 0xE7, 0x80, 0x9B, 0xF6, 0xE3, 0xB6, - 0x96, 0xF6, 0xE7, 0x81, 0x8A, 0xF6, 0xE7, 0x81, - 0xBD, 0xF6, 0xE7, 0x81, 0xB7, 0xF6, 0xE7, 0x82, - 0xAD, 0xF6, 0xF0, 0xA0, 0x94, 0xA5, 0xF6, 0xE7, - 0x85, 0x85, 0xF6, 0xF0, 0xA4, 0x89, 0xA3, 0xF6, - 0xE7, 0x86, 0x9C, 0xF6, 0xF0, 0xA4, 0x8E, 0xAB, - 0xF6, 0xE7, 0x88, 0xA8, 0xF6, 0xE7, 0x88, 0xB5, - 0xF6, 0xE7, 0x89, 0x90, 0xF6, 0xF0, 0xA4, 0x98, - 0x88, 0xF6, 0xE7, 0x8A, 0x80, 0xF6, 0xE7, 0x8A, - 0x95, 0xF6, 0xF0, 0xA4, 0x9C, 0xB5, 0xF6, 0xF0, - 0xA4, 0xA0, 0x94, 0xF6, 0xE7, 0x8D, 0xBA, 0xF6, - 0xE7, 0x8E, 0x8B, 0xF6, 0xE3, 0xBA, 0xAC, 0xF6, - 0xE7, 0x8E, 0xA5, 0xF6, 0xE3, 0xBA, 0xB8, 0xF6, - 0xE3, 0xBA, 0xB8, 0xF6, 0xE7, 0x91, 0x87, 0xF6, - 0xE7, 0x91, 0x9C, 0xF6, 0xE7, 0x91, 0xB1, 0xF6, - 0xE7, 0x92, 0x85, 0xF6, 0xE7, 0x93, 0x8A, 0xF6, - 0xE3, 0xBC, 0x9B, 0xF6, 0xE7, 0x94, 0xA4, 0xF6, - 0xF0, 0xA4, 0xB0, 0xB6, 0xF6, 0xE7, 0x94, 0xBE, - 0xF6, 0xF0, 0xA4, 0xB2, 0x92, 0xF6, 0xE7, 0x95, - 0xB0, 0xF6, 0xF0, 0xA2, 0x86, 0x9F, 0xF6, 0xE7, - 0x98, 0x90, 0xF6, 0xF0, 0xA4, 0xBE, 0xA1, 0xF6, - 0xF0, 0xA4, 0xBE, 0xB8, 0xF6, 0xF0, 0xA5, 0x81, - 0x84, 0xF6, 0xE3, 0xBF, 0xBC, 0xF6, 0xE4, 0x80, - 0x88, 0xF6, 0xE7, 0x9B, 0xB4, 0xF6, 0xF0, 0xA5, - 0x83, 0xB3, 0xF6, 0xF0, 0xA5, 0x83, 0xB2, 0xF6, - 0xF0, 0xA5, 0x84, 0x99, 0xF6, 0xF0, 0xA5, 0x84, - 0xB3, 0xF6, 0xE7, 0x9C, 0x9E, 0xF6, 0xE7, 0x9C, - 0x9F, 0xF6, 0xE7, 0x9C, 0x9F, 0xF6, 0xE7, 0x9D, - 0x8A, 0xF6, 0xE4, 0x80, 0xB9, 0xF6, 0xE7, 0x9E, - 0x8B, 0xF6, 0xE4, 0x81, 0x86, 0xF6, 0xE4, 0x82, - 0x96, 0xF6, 0xF0, 0xA5, 0x90, 0x9D, 0xF6, 0xE7, - 0xA1, 0x8E, 0xF6, 0xE7, 0xA2, 0x8C, 0xF6, 0xE7, - 0xA3, 0x8C, 0xF6, 0xE4, 0x83, 0xA3, 0xF6, 0xF0, - 0xA5, 0x98, 0xA6, 0xF6, 0xE7, 0xA5, 0x96, 0xF6, - 0xF0, 0xA5, 0x9A, 0x9A, 0xF6, 0xF0, 0xA5, 0x9B, - 0x85, 0xF6, 0xE7, 0xA6, 0x8F, 0xF6, 0xE7, 0xA7, - 0xAB, 0xF6, 0xE4, 0x84, 0xAF, 0xF6, 0xE7, 0xA9, - 0x80, 0xF6, 0xE7, 0xA9, 0x8A, 0xF6, 0xE7, 0xA9, - 0x8F, 0xF6, 0xF0, 0xA5, 0xA5, 0xBC, 0xF6, 0xF0, - 0xA5, 0xAA, 0xA7, 0xF6, 0xF0, 0xA5, 0xAA, 0xA7, - 0xF6, 0xE7, 0xAB, 0xAE, 0xF6, 0xE4, 0x88, 0x82, - 0xF6, 0xF0, 0xA5, 0xAE, 0xAB, 0xF6, 0xE7, 0xAF, - 0x86, 0xF6, 0xE7, 0xAF, 0x89, 0xF6, 0xE4, 0x88, - 0xA7, 0xF6, 0xF0, 0xA5, 0xB2, 0x80, 0xF6, 0xE7, - 0xB3, 0x92, 0xF6, 0xE4, 0x8A, 0xA0, 0xF6, 0xE7, - 0xB3, 0xA8, 0xF6, 0xE7, 0xB3, 0xA3, 0xF6, 0xE7, - 0xB4, 0x80, 0xF6, 0xF0, 0xA5, 0xBE, 0x86, 0xF6, - 0xE7, 0xB5, 0xA3, 0xF6, 0xE4, 0x8C, 0x81, 0xF6, - 0xE7, 0xB7, 0x87, 0xF6, 0xE7, 0xB8, 0x82, 0xF6, - 0xE7, 0xB9, 0x85, 0xF6, 0xE4, 0x8C, 0xB4, 0xF6, - 0xF0, 0xA6, 0x88, 0xA8, 0xF6, 0xF0, 0xA6, 0x89, - 0x87, 0xF6, 0xE4, 0x8D, 0x99, 0xF6, 0xF0, 0xA6, - 0x8B, 0x99, 0xF6, 0xE7, 0xBD, 0xBA, 0xF6, 0xF0, - 0xA6, 0x8C, 0xBE, 0xF6, 0xE7, 0xBE, 0x95, 0xF6, - 0xE7, 0xBF, 0xBA, 0xF6, 0xE8, 0x80, 0x85, 0xF6, - 0xF0, 0xA6, 0x93, 0x9A, 0xF6, 0xF0, 0xA6, 0x94, - 0xA3, 0xF6, 0xE8, 0x81, 0xA0, 0xF6, 0xF0, 0xA6, - 0x96, 0xA8, 0xF6, 0xE8, 0x81, 0xB0, 0xF6, 0xF0, - 0xA3, 0x8D, 0x9F, 0xF6, 0xE4, 0x8F, 0x95, 0xF6, - 0xE8, 0x82, 0xB2, 0xF6, 0xE8, 0x84, 0x83, 0xF6, - 0xE4, 0x90, 0x8B, 0xF6, 0xE8, 0x84, 0xBE, 0xF6, - 0xE5, 0xAA, 0xB5, 0xF6, 0xF0, 0xA6, 0x9E, 0xA7, - 0xF6, 0xF0, 0xA6, 0x9E, 0xB5, 0xF6, 0xF0, 0xA3, - 0x8E, 0x93, 0xF6, 0xF0, 0xA3, 0x8E, 0x9C, 0xF6, - 0xE8, 0x88, 0x81, 0xF6, 0xE8, 0x88, 0x84, 0xF6, - 0xE8, 0xBE, 0x9E, 0xF6, 0xE4, 0x91, 0xAB, 0xF6, - 0xE8, 0x8A, 0x91, 0xF6, 0xE8, 0x8A, 0x8B, 0xF6, - 0xE8, 0x8A, 0x9D, 0xF6, 0xE5, 0x8A, 0xB3, 0xF6, - 0xE8, 0x8A, 0xB1, 0xF6, 0xE8, 0x8A, 0xB3, 0xF6, - 0xE8, 0x8A, 0xBD, 0xF6, 0xE8, 0x8B, 0xA6, 0xF6, - 0xF0, 0xA6, 0xAC, 0xBC, 0xF6, 0xE8, 0x8B, 0xA5, - 0xF6, 0xE8, 0x8C, 0x9D, 0xF6, 0xE8, 0x8D, 0xA3, - 0xF6, 0xE8, 0x8E, 0xAD, 0xF6, 0xE8, 0x8C, 0xA3, - 0xF6, 0xE8, 0x8E, 0xBD, 0xF6, 0xE8, 0x8F, 0xA7, - 0xF6, 0xE8, 0x91, 0x97, 0xF6, 0xE8, 0x8D, 0x93, - 0xF6, 0xE8, 0x8F, 0x8A, 0xF6, 0xE8, 0x8F, 0x8C, - 0xF6, 0xE8, 0x8F, 0x9C, 0xF6, 0xF0, 0xA6, 0xB0, - 0xB6, 0xF6, 0xF0, 0xA6, 0xB5, 0xAB, 0xF6, 0xF0, - 0xA6, 0xB3, 0x95, 0xF6, 0xE4, 0x94, 0xAB, 0xF6, - 0xE8, 0x93, 0xB1, 0xF6, 0xE8, 0x93, 0xB3, 0xF6, - 0xE8, 0x94, 0x96, 0xF6, 0xF0, 0xA7, 0x8F, 0x8A, - 0xF6, 0xE8, 0x95, 0xA4, 0xF6, 0xF0, 0xA6, 0xBC, - 0xAC, 0xF6, 0xE4, 0x95, 0x9D, 0xF6, 0xE4, 0x95, - 0xA1, 0xF6, 0xF0, 0xA6, 0xBE, 0xB1, 0xF6, 0xF0, - 0xA7, 0x83, 0x92, 0xF6, 0xE4, 0x95, 0xAB, 0xF6, - 0xE8, 0x99, 0x90, 0xF6, 0xE8, 0x99, 0x9C, 0xF6, - 0xE8, 0x99, 0xA7, 0xF6, 0xE8, 0x99, 0xA9, 0xF6, - 0xE8, 0x9A, 0xA9, 0xF6, 0xE8, 0x9A, 0x88, 0xF6, - 0xE8, 0x9C, 0x8E, 0xF6, 0xE8, 0x9B, 0xA2, 0xF6, - 0xE8, 0x9D, 0xB9, 0xF6, 0xE8, 0x9C, 0xA8, 0xF6, - 0xE8, 0x9D, 0xAB, 0xF6, 0xE8, 0x9E, 0x86, 0xF6, - 0xE4, 0x97, 0x97, 0xF6, 0xE8, 0x9F, 0xA1, 0xF6, - 0xE8, 0xA0, 0x81, 0xF6, 0xE4, 0x97, 0xB9, 0xF6, - 0xE8, 0xA1, 0xA0, 0xF6, 0xE8, 0xA1, 0xA3, 0xF6, - 0xF0, 0xA7, 0x99, 0xA7, 0xF6, 0xE8, 0xA3, 0x97, - 0xF6, 0xE8, 0xA3, 0x9E, 0xF6, 0xE4, 0x98, 0xB5, - 0xF6, 0xE8, 0xA3, 0xBA, 0xF6, 0xE3, 0x92, 0xBB, - 0xF6, 0xF0, 0xA7, 0xA2, 0xAE, 0xF6, 0xF0, 0xA7, - 0xA5, 0xA6, 0xF6, 0xE4, 0x9A, 0xBE, 0xF6, 0xE4, - 0x9B, 0x87, 0xF6, 0xE8, 0xAA, 0xA0, 0xF6, 0xE8, - 0xAB, 0xAD, 0xF6, 0xE8, 0xAE, 0x8A, 0xF6, 0xE8, - 0xB1, 0x95, 0xF6, 0xF0, 0xA7, 0xB2, 0xA8, 0xF6, - 0xE8, 0xB2, 0xAB, 0xF6, 0xE8, 0xB3, 0x81, 0xF6, - 0xE8, 0xB4, 0x9B, 0xF6, 0xE8, 0xB5, 0xB7, 0xF6, - 0xF0, 0xA7, 0xBC, 0xAF, 0xF6, 0xF0, 0xA0, 0xA0, - 0x84, 0xF6, 0xE8, 0xB7, 0x8B, 0xF6, 0xE8, 0xB6, - 0xBC, 0xF6, 0xE8, 0xB7, 0xB0, 0xF6, 0xF0, 0xA0, - 0xA3, 0x9E, 0xF6, 0xE8, 0xBB, 0x94, 0xF6, 0xE8, - 0xBC, 0xB8, 0xF6, 0xF0, 0xA8, 0x97, 0x92, 0xF6, - 0xF0, 0xA8, 0x97, 0xAD, 0xF6, 0xE9, 0x82, 0x94, - 0xF6, 0xE9, 0x83, 0xB1, 0xF6, 0xE9, 0x84, 0x91, - 0xF6, 0xF0, 0xA8, 0x9C, 0xAE, 0xF6, 0xE9, 0x84, - 0x9B, 0xF6, 0xE9, 0x88, 0xB8, 0xF6, 0xE9, 0x8B, - 0x97, 0xF6, 0xE9, 0x8B, 0x98, 0xF6, 0xE9, 0x89, - 0xBC, 0xF6, 0xE9, 0x8F, 0xB9, 0xF6, 0xE9, 0x90, - 0x95, 0xF6, 0xF0, 0xA8, 0xAF, 0xBA, 0xF6, 0xE9, - 0x96, 0x8B, 0xF6, 0xE4, 0xA6, 0x95, 0xF6, 0xE9, - 0x96, 0xB7, 0xF6, 0xF0, 0xA8, 0xB5, 0xB7, 0xF6, - 0xE4, 0xA7, 0xA6, 0xF6, 0xE9, 0x9B, 0x83, 0xF6, - 0xE5, 0xB6, 0xB2, 0xF6, 0xE9, 0x9C, 0xA3, 0xF6, - 0xF0, 0xA9, 0x85, 0x85, 0xF6, 0xF0, 0xA9, 0x88, - 0x9A, 0xF6, 0xE4, 0xA9, 0xAE, 0xF6, 0xE4, 0xA9, - 0xB6, 0xF6, 0xE9, 0x9F, 0xA0, 0xF6, 0xF0, 0xA9, - 0x90, 0x8A, 0xF6, 0xE4, 0xAA, 0xB2, 0xF6, 0xF0, - 0xA9, 0x92, 0x96, 0xF6, 0xE9, 0xA0, 0x8B, 0xF6, - 0xE9, 0xA0, 0x8B, 0xF6, 0xE9, 0xA0, 0xA9, 0xF6, - 0xF0, 0xA9, 0x96, 0xB6, 0xF6, 0xE9, 0xA3, 0xA2, - 0xF6, 0xE4, 0xAC, 0xB3, 0xF6, 0xE9, 0xA4, 0xA9, - 0xF6, 0xE9, 0xA6, 0xA7, 0xF6, 0xE9, 0xA7, 0x82, - 0xF6, 0xE9, 0xA7, 0xBE, 0xF6, 0xE4, 0xAF, 0x8E, - 0xF6, 0xF0, 0xA9, 0xAC, 0xB0, 0xF6, 0xE9, 0xAC, - 0x92, 0xF6, 0xE9, 0xB1, 0x80, 0xF6, 0xE9, 0xB3, - 0xBD, 0xF6, 0xE4, 0xB3, 0x8E, 0xF6, 0xE4, 0xB3, - 0xAD, 0xF6, 0xE9, 0xB5, 0xA7, 0xF6, 0xF0, 0xAA, - 0x83, 0x8E, 0xF6, 0xE4, 0xB3, 0xB8, 0xF6, 0xF0, - 0xAA, 0x84, 0x85, 0xF6, 0xF0, 0xAA, 0x88, 0x8E, - 0xF6, 0xF0, 0xAA, 0x8A, 0x91, 0xF6, 0xE9, 0xBA, - 0xBB, 0xF6, 0xE4, 0xB5, 0x96, 0xF6, 0xE9, 0xBB, - 0xB9, 0xF6, 0xE9, 0xBB, 0xBE, 0xF6, 0xE9, 0xBC, - 0x85, 0xF6, 0xE9, 0xBC, 0x8F, 0xF6, 0xE9, 0xBC, - 0x96, 0xF6, 0xE9, 0xBC, 0xBB, 0xF6, 0xF0, 0xAA, - 0x98, 0x80, - }, -}; - -static const uchar_t u8_case_common_b2_tbl[2][2][256] = { - { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, 1, 2, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, 3, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 4, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - - }, - { - { - 0, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, 1, 2, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, 3, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - { - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - 4, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - N_, N_, N_, N_, N_, N_, N_, N_, - }, - - }, - -}; - -static const u8_displacement_t u8_tolower_b3_tbl[2][5][256] = { - { - { /* Third byte table 0. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { 0, 0 }, - { 1, 60 }, { 2, 123 }, { 3, 185 }, { 4, 257 }, - { 5, 321 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 6, 373 }, { 7, 439 }, - { 8, 465 }, { 9, 561 }, { 10, 593 }, { 11, 649 }, - { 12, 703 }, { 13, 749 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 1. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 14, 795 }, { 15, 891 }, { 16, 987 }, { 17, 1068 }, - { 18, 1155 }, { 19, 1245 }, { 20, 1299 }, { 21, 1386 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 2. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 22, 1443 }, { 23, 1448 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 24, 1496 }, { 25, 1526 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 3. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 26, 1574 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 4. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 27, 1652 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - }, - { - { /* Third byte table 0. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { 0, 0 }, - { 1, 60 }, { 2, 123 }, { 3, 185 }, { 4, 257 }, - { 5, 321 }, { 6, 383 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 7, 401 }, { 8, 467 }, - { 9, 505 }, { 10, 601 }, { 11, 633 }, { 12, 689 }, - { 13, 753 }, { 14, 803 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 1. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 15, 849 }, { 16, 945 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 17, 963 }, { 18, 1059 }, { 19, 1155 }, { 20, 1236 }, - { 21, 1323 }, { 22, 1413 }, { 23, 1467 }, { 24, 1554 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 2. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 25, 1611 }, { 26, 1619 }, { 27, 1667 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 28, 1670 }, { 29, 1700 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 30, 1748 }, { 31, 1889 }, { 32, 1911 }, { 33, 2007 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 3. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 34, 2061 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 4. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 35, 2139 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - }, -}; - -static const uchar_t u8_tolower_b4_tbl[2][36][257] = { - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 46, 48, 50, 52, 54, 56, 58, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 34, 34, 36, 36, 38, 38, 40, - 40, 42, 42, 44, 44, 46, 46, 48, - 48, 49, 49, 51, 51, 53, 53, 55, - 55, 55, 57, 57, 59, 59, 61, 61, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 8, 10, 10, 12, 12, 14, - 14, 16, 16, 18, 18, 20, 20, 22, - 22, 24, 24, 26, 26, 28, 28, 30, - 30, 32, 32, 34, 34, 36, 36, 38, - 38, 40, 40, 42, 42, 44, 44, 46, - 46, 48, 48, 50, 50, 52, 52, 54, - 54, 56, 58, 58, 60, 60, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 4, 4, 6, 6, 8, - 10, 10, 12, 14, 16, 16, 16, 18, - 20, 22, 24, 24, 26, 28, 28, 30, - 32, 34, 34, 34, 34, 36, 38, 38, - 40, 42, 42, 44, 44, 46, 46, 48, - 50, 50, 52, 52, 52, 54, 54, 56, - 58, 58, 60, 62, 64, 64, 66, 66, - 68, 70, 70, 70, 70, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 4, 4, - 6, 8, 8, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 28, 30, - 30, 32, 32, 34, 34, 36, 36, 38, - 38, 40, 40, 42, 42, 44, 44, 46, - 46, 46, 48, 50, 50, 52, 52, 54, - 56, 58, 58, 60, 60, 62, 62, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 34, 34, 36, 36, 38, 38, 40, - 40, 42, 42, 44, 44, 46, 46, 48, - 48, 50, 50, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 2, 4, 6, 8, 8, 10, 10, 12, - 14, 14, 16, 18, 20, 22, 24, 26, - 28, 30, 32, 34, 36, 38, 40, 42, - 44, 46, 48, 48, 50, 52, 54, 56, - 58, 60, 62, 64, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 24, 24, 24, 24, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - 64, 66, 68, 70, 72, 74, 76, 78, - 80, 82, 84, 86, 88, 90, 92, 94, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 34, 34, 36, 36, 38, 38, 40, - 40, 42, 42, 44, 44, 46, 46, 48, - 48, 50, 50, 52, 52, 54, 54, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 14, 16, 16, 18, 18, 20, 20, 22, - 22, 24, 24, 26, 26, 28, 28, 30, - 30, 32, 32, 34, 34, 36, 36, 38, - 38, 40, 40, 42, 42, 44, 44, 46, - 46, 48, 48, 50, 50, 52, 52, 52, - 52, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 18, 20, 22, 24, 26, 28, - 30, 32, 34, 36, 38, 40, 42, 44, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 36, - 36, 39, 39, 42, 42, 45, 45, 48, - 48, 51, 51, 54, 54, 57, 57, 60, - 60, 63, 63, 66, 66, 69, 69, 72, - 72, 75, 75, 78, 78, 81, 81, 84, - 84, 87, 87, 90, 90, 93, 93, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 36, - 36, 39, 39, 42, 42, 45, 45, 48, - 48, 51, 51, 54, 54, 57, 57, 60, - 60, 63, 63, 66, 66, 69, 69, 72, - 72, 75, 75, 78, 78, 81, 81, 84, - 84, 87, 87, 90, 90, 93, 93, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, - 33, 36, 36, 39, 39, 42, 42, 45, - 45, 48, 48, 51, 51, 54, 54, 57, - 57, 60, 60, 63, 63, 66, 66, 69, - 69, 72, 72, 75, 75, 78, 78, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 36, - 36, 39, 39, 42, 42, 45, 45, 48, - 48, 51, 51, 54, 54, 57, 57, 60, - 60, 63, 63, 66, 66, 69, 69, 72, - 72, 75, 75, 78, 78, 81, 81, 84, - 84, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 27, 30, 33, 36, 39, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 45, 48, 51, 54, 57, 60, 63, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 69, 72, 75, 78, 81, 84, 87, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 21, 21, 24, 24, 27, 27, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 33, 36, 39, 42, 45, 48, 51, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 75, 78, 81, 84, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 18, 21, 24, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 30, 33, 36, 39, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 45, 48, 51, 54, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 2, 2, 2, 3, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, - 6, 9, 12, 15, 18, 21, 24, 27, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 6, 9, 12, 15, 18, - 21, 24, 27, 30, 33, 36, 39, 42, - 45, 48, 51, 54, 57, 60, 63, 66, - 69, 72, 75, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, - 152, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - }, - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 46, 48, 50, 52, 54, 56, 58, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, - 60, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 34, 34, 36, 36, 38, 38, 40, - 40, 42, 42, 44, 44, 46, 46, 48, - 48, 49, 49, 51, 51, 53, 53, 55, - 55, 55, 57, 57, 59, 59, 61, 61, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 8, 10, 10, 12, 12, 14, - 14, 16, 16, 18, 18, 20, 20, 22, - 22, 24, 24, 26, 26, 28, 28, 30, - 30, 32, 32, 34, 34, 36, 36, 38, - 38, 40, 40, 42, 42, 44, 44, 46, - 46, 48, 48, 50, 50, 52, 52, 54, - 54, 56, 58, 58, 60, 60, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 4, 4, 6, 6, 8, - 10, 10, 12, 14, 16, 16, 16, 18, - 20, 22, 24, 24, 26, 28, 28, 30, - 32, 34, 34, 34, 34, 36, 38, 38, - 40, 42, 42, 44, 44, 46, 46, 48, - 50, 50, 52, 52, 52, 54, 54, 56, - 58, 58, 60, 62, 64, 64, 66, 66, - 68, 70, 70, 70, 70, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 4, 4, - 6, 8, 8, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 28, 30, - 30, 32, 32, 34, 34, 36, 36, 38, - 38, 40, 40, 42, 42, 44, 44, 46, - 46, 46, 48, 50, 50, 52, 52, 54, - 56, 58, 58, 60, 60, 62, 62, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 34, 34, 36, 36, 38, 38, 40, - 40, 42, 42, 44, 44, 46, 46, 48, - 48, 50, 50, 52, 52, 52, 52, 52, - 52, 52, 52, 55, 57, 57, 59, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 6, 8, 10, - 10, 12, 12, 14, 14, 16, 16, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 2, 4, 6, 8, 8, 10, 10, 12, - 14, 14, 16, 18, 20, 22, 24, 26, - 28, 30, 32, 34, 36, 38, 40, 42, - 44, 46, 48, 48, 50, 52, 54, 56, - 58, 60, 62, 64, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 24, 24, 24, 24, 26, 26, 26, - 28, 28, 30, 32, 32, 32, 34, 36, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - 64, 66, 68, 70, 72, 74, 76, 78, - 80, 82, 84, 86, 88, 90, 92, 94, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 34, 34, 36, 36, 38, 38, 40, - 40, 42, 42, 44, 44, 46, 46, 48, - 48, 50, 50, 52, 52, 54, 54, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 4, 6, 6, 8, 8, - 10, 10, 12, 12, 14, 14, 16, 16, - 16, 18, 18, 20, 20, 22, 22, 24, - 24, 26, 26, 28, 28, 30, 30, 32, - 32, 34, 34, 36, 36, 38, 38, 40, - 40, 42, 42, 44, 44, 46, 46, 48, - 48, 50, 50, 52, 52, 54, 54, 56, - 56, 58, 58, 60, 60, 62, 62, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 12, 12, 14, 14, 16, - 16, 18, 18, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 22, 24, 26, 28, 30, 32, - 34, 36, 38, 40, 42, 44, 46, 48, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 36, - 36, 39, 39, 42, 42, 45, 45, 48, - 48, 51, 51, 54, 54, 57, 57, 60, - 60, 63, 63, 66, 66, 69, 69, 72, - 72, 75, 75, 78, 78, 81, 81, 84, - 84, 87, 87, 90, 90, 93, 93, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 36, - 36, 39, 39, 42, 42, 45, 45, 48, - 48, 51, 51, 54, 54, 57, 57, 60, - 60, 63, 63, 66, 66, 69, 69, 72, - 72, 75, 75, 78, 78, 81, 81, 84, - 84, 87, 87, 90, 90, 93, 93, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, - 33, 36, 36, 39, 39, 42, 42, 45, - 45, 48, 48, 51, 51, 54, 54, 57, - 57, 60, 60, 63, 63, 66, 66, 69, - 69, 72, 72, 75, 75, 78, 78, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 36, - 36, 39, 39, 42, 42, 45, 45, 48, - 48, 51, 51, 54, 54, 57, 57, 60, - 60, 63, 63, 66, 66, 69, 69, 72, - 72, 75, 75, 78, 78, 81, 81, 84, - 84, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 27, 30, 33, 36, 39, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 45, 48, 51, 54, 57, 60, 63, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 69, 72, 75, 78, 81, 84, 87, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 21, 21, 24, 24, 27, 27, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 33, 36, 39, 42, 45, 48, 51, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 75, 78, 81, 84, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 18, 21, 24, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 30, 33, 36, 39, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 45, 48, 51, 54, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 2, 2, 2, 3, 5, 5, 5, 5, - 5, 5, 5, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, - 6, 9, 12, 15, 18, 21, 24, 27, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 117, - 120, 123, 126, 129, 132, 135, 138, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, - 141, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 5, 8, 10, 10, 10, - 13, 13, 16, 16, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 36, - 36, 39, 39, 42, 42, 45, 45, 48, - 48, 51, 51, 54, 54, 57, 57, 60, - 60, 63, 63, 66, 66, 69, 69, 72, - 72, 75, 75, 78, 78, 81, 81, 84, - 84, 87, 87, 90, 90, 93, 93, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 6, 6, 9, 9, 12, - 12, 15, 15, 18, 18, 21, 21, 24, - 24, 27, 27, 30, 30, 33, 33, 36, - 36, 39, 39, 42, 42, 45, 45, 48, - 48, 51, 51, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 6, 9, 12, 15, 18, - 21, 24, 27, 30, 33, 36, 39, 42, - 45, 48, 51, 54, 57, 60, 63, 66, - 69, 72, 75, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140, 144, 148, 152, 156, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, - }, - }, -}; - -static const uchar_t u8_tolower_final_tbl[2][2299] = { - { - 0xC3, 0xA0, 0xC3, 0xA1, 0xC3, 0xA2, 0xC3, 0xA3, - 0xC3, 0xA4, 0xC3, 0xA5, 0xC3, 0xA6, 0xC3, 0xA7, - 0xC3, 0xA8, 0xC3, 0xA9, 0xC3, 0xAA, 0xC3, 0xAB, - 0xC3, 0xAC, 0xC3, 0xAD, 0xC3, 0xAE, 0xC3, 0xAF, - 0xC3, 0xB0, 0xC3, 0xB1, 0xC3, 0xB2, 0xC3, 0xB3, - 0xC3, 0xB4, 0xC3, 0xB5, 0xC3, 0xB6, 0xC3, 0xB8, - 0xC3, 0xB9, 0xC3, 0xBA, 0xC3, 0xBB, 0xC3, 0xBC, - 0xC3, 0xBD, 0xC3, 0xBE, 0xC4, 0x81, 0xC4, 0x83, - 0xC4, 0x85, 0xC4, 0x87, 0xC4, 0x89, 0xC4, 0x8B, - 0xC4, 0x8D, 0xC4, 0x8F, 0xC4, 0x91, 0xC4, 0x93, - 0xC4, 0x95, 0xC4, 0x97, 0xC4, 0x99, 0xC4, 0x9B, - 0xC4, 0x9D, 0xC4, 0x9F, 0xC4, 0xA1, 0xC4, 0xA3, - 0xC4, 0xA5, 0xC4, 0xA7, 0xC4, 0xA9, 0xC4, 0xAB, - 0xC4, 0xAD, 0xC4, 0xAF, 0x69, 0xC4, 0xB3, 0xC4, - 0xB5, 0xC4, 0xB7, 0xC4, 0xBA, 0xC4, 0xBC, 0xC4, - 0xBE, 0xC5, 0x80, 0xC5, 0x82, 0xC5, 0x84, 0xC5, - 0x86, 0xC5, 0x88, 0xC5, 0x8B, 0xC5, 0x8D, 0xC5, - 0x8F, 0xC5, 0x91, 0xC5, 0x93, 0xC5, 0x95, 0xC5, - 0x97, 0xC5, 0x99, 0xC5, 0x9B, 0xC5, 0x9D, 0xC5, - 0x9F, 0xC5, 0xA1, 0xC5, 0xA3, 0xC5, 0xA5, 0xC5, - 0xA7, 0xC5, 0xA9, 0xC5, 0xAB, 0xC5, 0xAD, 0xC5, - 0xAF, 0xC5, 0xB1, 0xC5, 0xB3, 0xC5, 0xB5, 0xC5, - 0xB7, 0xC3, 0xBF, 0xC5, 0xBA, 0xC5, 0xBC, 0xC5, - 0xBE, 0xC9, 0x93, 0xC6, 0x83, 0xC6, 0x85, 0xC9, - 0x94, 0xC6, 0x88, 0xC9, 0x96, 0xC9, 0x97, 0xC6, - 0x8C, 0xC7, 0x9D, 0xC9, 0x99, 0xC9, 0x9B, 0xC6, - 0x92, 0xC9, 0xA0, 0xC9, 0xA3, 0xC9, 0xA9, 0xC9, - 0xA8, 0xC6, 0x99, 0xC9, 0xAF, 0xC9, 0xB2, 0xC9, - 0xB5, 0xC6, 0xA1, 0xC6, 0xA3, 0xC6, 0xA5, 0xCA, - 0x80, 0xC6, 0xA8, 0xCA, 0x83, 0xC6, 0xAD, 0xCA, - 0x88, 0xC6, 0xB0, 0xCA, 0x8A, 0xCA, 0x8B, 0xC6, - 0xB4, 0xC6, 0xB6, 0xCA, 0x92, 0xC6, 0xB9, 0xC6, - 0xBD, 0xC7, 0x86, 0xC7, 0x86, 0xC7, 0x89, 0xC7, - 0x89, 0xC7, 0x8C, 0xC7, 0x8C, 0xC7, 0x8E, 0xC7, - 0x90, 0xC7, 0x92, 0xC7, 0x94, 0xC7, 0x96, 0xC7, - 0x98, 0xC7, 0x9A, 0xC7, 0x9C, 0xC7, 0x9F, 0xC7, - 0xA1, 0xC7, 0xA3, 0xC7, 0xA5, 0xC7, 0xA7, 0xC7, - 0xA9, 0xC7, 0xAB, 0xC7, 0xAD, 0xC7, 0xAF, 0xC7, - 0xB3, 0xC7, 0xB3, 0xC7, 0xB5, 0xC6, 0x95, 0xC6, - 0xBF, 0xC7, 0xB9, 0xC7, 0xBB, 0xC7, 0xBD, 0xC7, - 0xBF, 0xC8, 0x81, 0xC8, 0x83, 0xC8, 0x85, 0xC8, - 0x87, 0xC8, 0x89, 0xC8, 0x8B, 0xC8, 0x8D, 0xC8, - 0x8F, 0xC8, 0x91, 0xC8, 0x93, 0xC8, 0x95, 0xC8, - 0x97, 0xC8, 0x99, 0xC8, 0x9B, 0xC8, 0x9D, 0xC8, - 0x9F, 0xC6, 0x9E, 0xC8, 0xA3, 0xC8, 0xA5, 0xC8, - 0xA7, 0xC8, 0xA9, 0xC8, 0xAB, 0xC8, 0xAD, 0xC8, - 0xAF, 0xC8, 0xB1, 0xC8, 0xB3, 0xCE, 0xAC, 0xCE, - 0xAD, 0xCE, 0xAE, 0xCE, 0xAF, 0xCF, 0x8C, 0xCF, - 0x8D, 0xCF, 0x8E, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, - 0xB3, 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xB6, 0xCE, - 0xB7, 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, - 0xBB, 0xCE, 0xBC, 0xCE, 0xBD, 0xCE, 0xBE, 0xCE, - 0xBF, 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x83, 0xCF, - 0x84, 0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, 0xCF, - 0x88, 0xCF, 0x89, 0xCF, 0x8A, 0xCF, 0x8B, 0xCF, - 0x99, 0xCF, 0x9B, 0xCF, 0x9D, 0xCF, 0x9F, 0xCF, - 0xA1, 0xCF, 0xA3, 0xCF, 0xA5, 0xCF, 0xA7, 0xCF, - 0xA9, 0xCF, 0xAB, 0xCF, 0xAD, 0xCF, 0xAF, 0xCE, - 0xB8, 0xD1, 0x90, 0xD1, 0x91, 0xD1, 0x92, 0xD1, - 0x93, 0xD1, 0x94, 0xD1, 0x95, 0xD1, 0x96, 0xD1, - 0x97, 0xD1, 0x98, 0xD1, 0x99, 0xD1, 0x9A, 0xD1, - 0x9B, 0xD1, 0x9C, 0xD1, 0x9D, 0xD1, 0x9E, 0xD1, - 0x9F, 0xD0, 0xB0, 0xD0, 0xB1, 0xD0, 0xB2, 0xD0, - 0xB3, 0xD0, 0xB4, 0xD0, 0xB5, 0xD0, 0xB6, 0xD0, - 0xB7, 0xD0, 0xB8, 0xD0, 0xB9, 0xD0, 0xBA, 0xD0, - 0xBB, 0xD0, 0xBC, 0xD0, 0xBD, 0xD0, 0xBE, 0xD0, - 0xBF, 0xD1, 0x80, 0xD1, 0x81, 0xD1, 0x82, 0xD1, - 0x83, 0xD1, 0x84, 0xD1, 0x85, 0xD1, 0x86, 0xD1, - 0x87, 0xD1, 0x88, 0xD1, 0x89, 0xD1, 0x8A, 0xD1, - 0x8B, 0xD1, 0x8C, 0xD1, 0x8D, 0xD1, 0x8E, 0xD1, - 0x8F, 0xD1, 0xA1, 0xD1, 0xA3, 0xD1, 0xA5, 0xD1, - 0xA7, 0xD1, 0xA9, 0xD1, 0xAB, 0xD1, 0xAD, 0xD1, - 0xAF, 0xD1, 0xB1, 0xD1, 0xB3, 0xD1, 0xB5, 0xD1, - 0xB7, 0xD1, 0xB9, 0xD1, 0xBB, 0xD1, 0xBD, 0xD1, - 0xBF, 0xD2, 0x81, 0xD2, 0x8B, 0xD2, 0x8D, 0xD2, - 0x8F, 0xD2, 0x91, 0xD2, 0x93, 0xD2, 0x95, 0xD2, - 0x97, 0xD2, 0x99, 0xD2, 0x9B, 0xD2, 0x9D, 0xD2, - 0x9F, 0xD2, 0xA1, 0xD2, 0xA3, 0xD2, 0xA5, 0xD2, - 0xA7, 0xD2, 0xA9, 0xD2, 0xAB, 0xD2, 0xAD, 0xD2, - 0xAF, 0xD2, 0xB1, 0xD2, 0xB3, 0xD2, 0xB5, 0xD2, - 0xB7, 0xD2, 0xB9, 0xD2, 0xBB, 0xD2, 0xBD, 0xD2, - 0xBF, 0xD3, 0x82, 0xD3, 0x84, 0xD3, 0x86, 0xD3, - 0x88, 0xD3, 0x8A, 0xD3, 0x8C, 0xD3, 0x8E, 0xD3, - 0x91, 0xD3, 0x93, 0xD3, 0x95, 0xD3, 0x97, 0xD3, - 0x99, 0xD3, 0x9B, 0xD3, 0x9D, 0xD3, 0x9F, 0xD3, - 0xA1, 0xD3, 0xA3, 0xD3, 0xA5, 0xD3, 0xA7, 0xD3, - 0xA9, 0xD3, 0xAB, 0xD3, 0xAD, 0xD3, 0xAF, 0xD3, - 0xB1, 0xD3, 0xB3, 0xD3, 0xB5, 0xD3, 0xB9, 0xD4, - 0x81, 0xD4, 0x83, 0xD4, 0x85, 0xD4, 0x87, 0xD4, - 0x89, 0xD4, 0x8B, 0xD4, 0x8D, 0xD4, 0x8F, 0xD5, - 0xA1, 0xD5, 0xA2, 0xD5, 0xA3, 0xD5, 0xA4, 0xD5, - 0xA5, 0xD5, 0xA6, 0xD5, 0xA7, 0xD5, 0xA8, 0xD5, - 0xA9, 0xD5, 0xAA, 0xD5, 0xAB, 0xD5, 0xAC, 0xD5, - 0xAD, 0xD5, 0xAE, 0xD5, 0xAF, 0xD5, 0xB0, 0xD5, - 0xB1, 0xD5, 0xB2, 0xD5, 0xB3, 0xD5, 0xB4, 0xD5, - 0xB5, 0xD5, 0xB6, 0xD5, 0xB7, 0xD5, 0xB8, 0xD5, - 0xB9, 0xD5, 0xBA, 0xD5, 0xBB, 0xD5, 0xBC, 0xD5, - 0xBD, 0xD5, 0xBE, 0xD5, 0xBF, 0xD6, 0x80, 0xD6, - 0x81, 0xD6, 0x82, 0xD6, 0x83, 0xD6, 0x84, 0xD6, - 0x85, 0xD6, 0x86, 0xE1, 0xB8, 0x81, 0xE1, 0xB8, - 0x83, 0xE1, 0xB8, 0x85, 0xE1, 0xB8, 0x87, 0xE1, - 0xB8, 0x89, 0xE1, 0xB8, 0x8B, 0xE1, 0xB8, 0x8D, - 0xE1, 0xB8, 0x8F, 0xE1, 0xB8, 0x91, 0xE1, 0xB8, - 0x93, 0xE1, 0xB8, 0x95, 0xE1, 0xB8, 0x97, 0xE1, - 0xB8, 0x99, 0xE1, 0xB8, 0x9B, 0xE1, 0xB8, 0x9D, - 0xE1, 0xB8, 0x9F, 0xE1, 0xB8, 0xA1, 0xE1, 0xB8, - 0xA3, 0xE1, 0xB8, 0xA5, 0xE1, 0xB8, 0xA7, 0xE1, - 0xB8, 0xA9, 0xE1, 0xB8, 0xAB, 0xE1, 0xB8, 0xAD, - 0xE1, 0xB8, 0xAF, 0xE1, 0xB8, 0xB1, 0xE1, 0xB8, - 0xB3, 0xE1, 0xB8, 0xB5, 0xE1, 0xB8, 0xB7, 0xE1, - 0xB8, 0xB9, 0xE1, 0xB8, 0xBB, 0xE1, 0xB8, 0xBD, - 0xE1, 0xB8, 0xBF, 0xE1, 0xB9, 0x81, 0xE1, 0xB9, - 0x83, 0xE1, 0xB9, 0x85, 0xE1, 0xB9, 0x87, 0xE1, - 0xB9, 0x89, 0xE1, 0xB9, 0x8B, 0xE1, 0xB9, 0x8D, - 0xE1, 0xB9, 0x8F, 0xE1, 0xB9, 0x91, 0xE1, 0xB9, - 0x93, 0xE1, 0xB9, 0x95, 0xE1, 0xB9, 0x97, 0xE1, - 0xB9, 0x99, 0xE1, 0xB9, 0x9B, 0xE1, 0xB9, 0x9D, - 0xE1, 0xB9, 0x9F, 0xE1, 0xB9, 0xA1, 0xE1, 0xB9, - 0xA3, 0xE1, 0xB9, 0xA5, 0xE1, 0xB9, 0xA7, 0xE1, - 0xB9, 0xA9, 0xE1, 0xB9, 0xAB, 0xE1, 0xB9, 0xAD, - 0xE1, 0xB9, 0xAF, 0xE1, 0xB9, 0xB1, 0xE1, 0xB9, - 0xB3, 0xE1, 0xB9, 0xB5, 0xE1, 0xB9, 0xB7, 0xE1, - 0xB9, 0xB9, 0xE1, 0xB9, 0xBB, 0xE1, 0xB9, 0xBD, - 0xE1, 0xB9, 0xBF, 0xE1, 0xBA, 0x81, 0xE1, 0xBA, - 0x83, 0xE1, 0xBA, 0x85, 0xE1, 0xBA, 0x87, 0xE1, - 0xBA, 0x89, 0xE1, 0xBA, 0x8B, 0xE1, 0xBA, 0x8D, - 0xE1, 0xBA, 0x8F, 0xE1, 0xBA, 0x91, 0xE1, 0xBA, - 0x93, 0xE1, 0xBA, 0x95, 0xE1, 0xBA, 0xA1, 0xE1, - 0xBA, 0xA3, 0xE1, 0xBA, 0xA5, 0xE1, 0xBA, 0xA7, - 0xE1, 0xBA, 0xA9, 0xE1, 0xBA, 0xAB, 0xE1, 0xBA, - 0xAD, 0xE1, 0xBA, 0xAF, 0xE1, 0xBA, 0xB1, 0xE1, - 0xBA, 0xB3, 0xE1, 0xBA, 0xB5, 0xE1, 0xBA, 0xB7, - 0xE1, 0xBA, 0xB9, 0xE1, 0xBA, 0xBB, 0xE1, 0xBA, - 0xBD, 0xE1, 0xBA, 0xBF, 0xE1, 0xBB, 0x81, 0xE1, - 0xBB, 0x83, 0xE1, 0xBB, 0x85, 0xE1, 0xBB, 0x87, - 0xE1, 0xBB, 0x89, 0xE1, 0xBB, 0x8B, 0xE1, 0xBB, - 0x8D, 0xE1, 0xBB, 0x8F, 0xE1, 0xBB, 0x91, 0xE1, - 0xBB, 0x93, 0xE1, 0xBB, 0x95, 0xE1, 0xBB, 0x97, - 0xE1, 0xBB, 0x99, 0xE1, 0xBB, 0x9B, 0xE1, 0xBB, - 0x9D, 0xE1, 0xBB, 0x9F, 0xE1, 0xBB, 0xA1, 0xE1, - 0xBB, 0xA3, 0xE1, 0xBB, 0xA5, 0xE1, 0xBB, 0xA7, - 0xE1, 0xBB, 0xA9, 0xE1, 0xBB, 0xAB, 0xE1, 0xBB, - 0xAD, 0xE1, 0xBB, 0xAF, 0xE1, 0xBB, 0xB1, 0xE1, - 0xBB, 0xB3, 0xE1, 0xBB, 0xB5, 0xE1, 0xBB, 0xB7, - 0xE1, 0xBB, 0xB9, 0xE1, 0xBC, 0x80, 0xE1, 0xBC, - 0x81, 0xE1, 0xBC, 0x82, 0xE1, 0xBC, 0x83, 0xE1, - 0xBC, 0x84, 0xE1, 0xBC, 0x85, 0xE1, 0xBC, 0x86, - 0xE1, 0xBC, 0x87, 0xE1, 0xBC, 0x90, 0xE1, 0xBC, - 0x91, 0xE1, 0xBC, 0x92, 0xE1, 0xBC, 0x93, 0xE1, - 0xBC, 0x94, 0xE1, 0xBC, 0x95, 0xE1, 0xBC, 0xA0, - 0xE1, 0xBC, 0xA1, 0xE1, 0xBC, 0xA2, 0xE1, 0xBC, - 0xA3, 0xE1, 0xBC, 0xA4, 0xE1, 0xBC, 0xA5, 0xE1, - 0xBC, 0xA6, 0xE1, 0xBC, 0xA7, 0xE1, 0xBC, 0xB0, - 0xE1, 0xBC, 0xB1, 0xE1, 0xBC, 0xB2, 0xE1, 0xBC, - 0xB3, 0xE1, 0xBC, 0xB4, 0xE1, 0xBC, 0xB5, 0xE1, - 0xBC, 0xB6, 0xE1, 0xBC, 0xB7, 0xE1, 0xBD, 0x80, - 0xE1, 0xBD, 0x81, 0xE1, 0xBD, 0x82, 0xE1, 0xBD, - 0x83, 0xE1, 0xBD, 0x84, 0xE1, 0xBD, 0x85, 0xE1, - 0xBD, 0x91, 0xE1, 0xBD, 0x93, 0xE1, 0xBD, 0x95, - 0xE1, 0xBD, 0x97, 0xE1, 0xBD, 0xA0, 0xE1, 0xBD, - 0xA1, 0xE1, 0xBD, 0xA2, 0xE1, 0xBD, 0xA3, 0xE1, - 0xBD, 0xA4, 0xE1, 0xBD, 0xA5, 0xE1, 0xBD, 0xA6, - 0xE1, 0xBD, 0xA7, 0xE1, 0xBE, 0x80, 0xE1, 0xBE, - 0x81, 0xE1, 0xBE, 0x82, 0xE1, 0xBE, 0x83, 0xE1, - 0xBE, 0x84, 0xE1, 0xBE, 0x85, 0xE1, 0xBE, 0x86, - 0xE1, 0xBE, 0x87, 0xE1, 0xBE, 0x90, 0xE1, 0xBE, - 0x91, 0xE1, 0xBE, 0x92, 0xE1, 0xBE, 0x93, 0xE1, - 0xBE, 0x94, 0xE1, 0xBE, 0x95, 0xE1, 0xBE, 0x96, - 0xE1, 0xBE, 0x97, 0xE1, 0xBE, 0xA0, 0xE1, 0xBE, - 0xA1, 0xE1, 0xBE, 0xA2, 0xE1, 0xBE, 0xA3, 0xE1, - 0xBE, 0xA4, 0xE1, 0xBE, 0xA5, 0xE1, 0xBE, 0xA6, - 0xE1, 0xBE, 0xA7, 0xE1, 0xBE, 0xB0, 0xE1, 0xBE, - 0xB1, 0xE1, 0xBD, 0xB0, 0xE1, 0xBD, 0xB1, 0xE1, - 0xBE, 0xB3, 0xE1, 0xBD, 0xB2, 0xE1, 0xBD, 0xB3, - 0xE1, 0xBD, 0xB4, 0xE1, 0xBD, 0xB5, 0xE1, 0xBF, - 0x83, 0xE1, 0xBF, 0x90, 0xE1, 0xBF, 0x91, 0xE1, - 0xBD, 0xB6, 0xE1, 0xBD, 0xB7, 0xE1, 0xBF, 0xA0, - 0xE1, 0xBF, 0xA1, 0xE1, 0xBD, 0xBA, 0xE1, 0xBD, - 0xBB, 0xE1, 0xBF, 0xA5, 0xE1, 0xBD, 0xB8, 0xE1, - 0xBD, 0xB9, 0xE1, 0xBD, 0xBC, 0xE1, 0xBD, 0xBD, - 0xE1, 0xBF, 0xB3, 0xCF, 0x89, 0x6B, 0xC3, 0xA5, - 0xE2, 0x85, 0xB0, 0xE2, 0x85, 0xB1, 0xE2, 0x85, - 0xB2, 0xE2, 0x85, 0xB3, 0xE2, 0x85, 0xB4, 0xE2, - 0x85, 0xB5, 0xE2, 0x85, 0xB6, 0xE2, 0x85, 0xB7, - 0xE2, 0x85, 0xB8, 0xE2, 0x85, 0xB9, 0xE2, 0x85, - 0xBA, 0xE2, 0x85, 0xBB, 0xE2, 0x85, 0xBC, 0xE2, - 0x85, 0xBD, 0xE2, 0x85, 0xBE, 0xE2, 0x85, 0xBF, - 0xE2, 0x93, 0x90, 0xE2, 0x93, 0x91, 0xE2, 0x93, - 0x92, 0xE2, 0x93, 0x93, 0xE2, 0x93, 0x94, 0xE2, - 0x93, 0x95, 0xE2, 0x93, 0x96, 0xE2, 0x93, 0x97, - 0xE2, 0x93, 0x98, 0xE2, 0x93, 0x99, 0xE2, 0x93, - 0x9A, 0xE2, 0x93, 0x9B, 0xE2, 0x93, 0x9C, 0xE2, - 0x93, 0x9D, 0xE2, 0x93, 0x9E, 0xE2, 0x93, 0x9F, - 0xE2, 0x93, 0xA0, 0xE2, 0x93, 0xA1, 0xE2, 0x93, - 0xA2, 0xE2, 0x93, 0xA3, 0xE2, 0x93, 0xA4, 0xE2, - 0x93, 0xA5, 0xE2, 0x93, 0xA6, 0xE2, 0x93, 0xA7, - 0xE2, 0x93, 0xA8, 0xE2, 0x93, 0xA9, 0xEF, 0xBD, - 0x81, 0xEF, 0xBD, 0x82, 0xEF, 0xBD, 0x83, 0xEF, - 0xBD, 0x84, 0xEF, 0xBD, 0x85, 0xEF, 0xBD, 0x86, - 0xEF, 0xBD, 0x87, 0xEF, 0xBD, 0x88, 0xEF, 0xBD, - 0x89, 0xEF, 0xBD, 0x8A, 0xEF, 0xBD, 0x8B, 0xEF, - 0xBD, 0x8C, 0xEF, 0xBD, 0x8D, 0xEF, 0xBD, 0x8E, - 0xEF, 0xBD, 0x8F, 0xEF, 0xBD, 0x90, 0xEF, 0xBD, - 0x91, 0xEF, 0xBD, 0x92, 0xEF, 0xBD, 0x93, 0xEF, - 0xBD, 0x94, 0xEF, 0xBD, 0x95, 0xEF, 0xBD, 0x96, - 0xEF, 0xBD, 0x97, 0xEF, 0xBD, 0x98, 0xEF, 0xBD, - 0x99, 0xEF, 0xBD, 0x9A, 0xF0, 0x90, 0x90, 0xA8, - 0xF0, 0x90, 0x90, 0xA9, 0xF0, 0x90, 0x90, 0xAA, - 0xF0, 0x90, 0x90, 0xAB, 0xF0, 0x90, 0x90, 0xAC, - 0xF0, 0x90, 0x90, 0xAD, 0xF0, 0x90, 0x90, 0xAE, - 0xF0, 0x90, 0x90, 0xAF, 0xF0, 0x90, 0x90, 0xB0, - 0xF0, 0x90, 0x90, 0xB1, 0xF0, 0x90, 0x90, 0xB2, - 0xF0, 0x90, 0x90, 0xB3, 0xF0, 0x90, 0x90, 0xB4, - 0xF0, 0x90, 0x90, 0xB5, 0xF0, 0x90, 0x90, 0xB6, - 0xF0, 0x90, 0x90, 0xB7, 0xF0, 0x90, 0x90, 0xB8, - 0xF0, 0x90, 0x90, 0xB9, 0xF0, 0x90, 0x90, 0xBA, - 0xF0, 0x90, 0x90, 0xBB, 0xF0, 0x90, 0x90, 0xBC, - 0xF0, 0x90, 0x90, 0xBD, 0xF0, 0x90, 0x90, 0xBE, - 0xF0, 0x90, 0x90, 0xBF, 0xF0, 0x90, 0x91, 0x80, - 0xF0, 0x90, 0x91, 0x81, 0xF0, 0x90, 0x91, 0x82, - 0xF0, 0x90, 0x91, 0x83, 0xF0, 0x90, 0x91, 0x84, - 0xF0, 0x90, 0x91, 0x85, 0xF0, 0x90, 0x91, 0x86, - 0xF0, 0x90, 0x91, 0x87, 0xF0, 0x90, 0x91, 0x88, - 0xF0, 0x90, 0x91, 0x89, 0xF0, 0x90, 0x91, 0x8A, - 0xF0, 0x90, 0x91, 0x8B, 0xF0, 0x90, 0x91, 0x8C, - 0xF0, 0x90, 0x91, 0x8D, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - }, - { - 0xC3, 0xA0, 0xC3, 0xA1, 0xC3, 0xA2, 0xC3, 0xA3, - 0xC3, 0xA4, 0xC3, 0xA5, 0xC3, 0xA6, 0xC3, 0xA7, - 0xC3, 0xA8, 0xC3, 0xA9, 0xC3, 0xAA, 0xC3, 0xAB, - 0xC3, 0xAC, 0xC3, 0xAD, 0xC3, 0xAE, 0xC3, 0xAF, - 0xC3, 0xB0, 0xC3, 0xB1, 0xC3, 0xB2, 0xC3, 0xB3, - 0xC3, 0xB4, 0xC3, 0xB5, 0xC3, 0xB6, 0xC3, 0xB8, - 0xC3, 0xB9, 0xC3, 0xBA, 0xC3, 0xBB, 0xC3, 0xBC, - 0xC3, 0xBD, 0xC3, 0xBE, 0xC4, 0x81, 0xC4, 0x83, - 0xC4, 0x85, 0xC4, 0x87, 0xC4, 0x89, 0xC4, 0x8B, - 0xC4, 0x8D, 0xC4, 0x8F, 0xC4, 0x91, 0xC4, 0x93, - 0xC4, 0x95, 0xC4, 0x97, 0xC4, 0x99, 0xC4, 0x9B, - 0xC4, 0x9D, 0xC4, 0x9F, 0xC4, 0xA1, 0xC4, 0xA3, - 0xC4, 0xA5, 0xC4, 0xA7, 0xC4, 0xA9, 0xC4, 0xAB, - 0xC4, 0xAD, 0xC4, 0xAF, 0x69, 0xC4, 0xB3, 0xC4, - 0xB5, 0xC4, 0xB7, 0xC4, 0xBA, 0xC4, 0xBC, 0xC4, - 0xBE, 0xC5, 0x80, 0xC5, 0x82, 0xC5, 0x84, 0xC5, - 0x86, 0xC5, 0x88, 0xC5, 0x8B, 0xC5, 0x8D, 0xC5, - 0x8F, 0xC5, 0x91, 0xC5, 0x93, 0xC5, 0x95, 0xC5, - 0x97, 0xC5, 0x99, 0xC5, 0x9B, 0xC5, 0x9D, 0xC5, - 0x9F, 0xC5, 0xA1, 0xC5, 0xA3, 0xC5, 0xA5, 0xC5, - 0xA7, 0xC5, 0xA9, 0xC5, 0xAB, 0xC5, 0xAD, 0xC5, - 0xAF, 0xC5, 0xB1, 0xC5, 0xB3, 0xC5, 0xB5, 0xC5, - 0xB7, 0xC3, 0xBF, 0xC5, 0xBA, 0xC5, 0xBC, 0xC5, - 0xBE, 0xC9, 0x93, 0xC6, 0x83, 0xC6, 0x85, 0xC9, - 0x94, 0xC6, 0x88, 0xC9, 0x96, 0xC9, 0x97, 0xC6, - 0x8C, 0xC7, 0x9D, 0xC9, 0x99, 0xC9, 0x9B, 0xC6, - 0x92, 0xC9, 0xA0, 0xC9, 0xA3, 0xC9, 0xA9, 0xC9, - 0xA8, 0xC6, 0x99, 0xC9, 0xAF, 0xC9, 0xB2, 0xC9, - 0xB5, 0xC6, 0xA1, 0xC6, 0xA3, 0xC6, 0xA5, 0xCA, - 0x80, 0xC6, 0xA8, 0xCA, 0x83, 0xC6, 0xAD, 0xCA, - 0x88, 0xC6, 0xB0, 0xCA, 0x8A, 0xCA, 0x8B, 0xC6, - 0xB4, 0xC6, 0xB6, 0xCA, 0x92, 0xC6, 0xB9, 0xC6, - 0xBD, 0xC7, 0x86, 0xC7, 0x86, 0xC7, 0x89, 0xC7, - 0x89, 0xC7, 0x8C, 0xC7, 0x8C, 0xC7, 0x8E, 0xC7, - 0x90, 0xC7, 0x92, 0xC7, 0x94, 0xC7, 0x96, 0xC7, - 0x98, 0xC7, 0x9A, 0xC7, 0x9C, 0xC7, 0x9F, 0xC7, - 0xA1, 0xC7, 0xA3, 0xC7, 0xA5, 0xC7, 0xA7, 0xC7, - 0xA9, 0xC7, 0xAB, 0xC7, 0xAD, 0xC7, 0xAF, 0xC7, - 0xB3, 0xC7, 0xB3, 0xC7, 0xB5, 0xC6, 0x95, 0xC6, - 0xBF, 0xC7, 0xB9, 0xC7, 0xBB, 0xC7, 0xBD, 0xC7, - 0xBF, 0xC8, 0x81, 0xC8, 0x83, 0xC8, 0x85, 0xC8, - 0x87, 0xC8, 0x89, 0xC8, 0x8B, 0xC8, 0x8D, 0xC8, - 0x8F, 0xC8, 0x91, 0xC8, 0x93, 0xC8, 0x95, 0xC8, - 0x97, 0xC8, 0x99, 0xC8, 0x9B, 0xC8, 0x9D, 0xC8, - 0x9F, 0xC6, 0x9E, 0xC8, 0xA3, 0xC8, 0xA5, 0xC8, - 0xA7, 0xC8, 0xA9, 0xC8, 0xAB, 0xC8, 0xAD, 0xC8, - 0xAF, 0xC8, 0xB1, 0xC8, 0xB3, 0xE2, 0xB1, 0xA5, - 0xC8, 0xBC, 0xC6, 0x9A, 0xE2, 0xB1, 0xA6, 0xC9, - 0x82, 0xC6, 0x80, 0xCA, 0x89, 0xCA, 0x8C, 0xC9, - 0x87, 0xC9, 0x89, 0xC9, 0x8B, 0xC9, 0x8D, 0xC9, - 0x8F, 0xCE, 0xAC, 0xCE, 0xAD, 0xCE, 0xAE, 0xCE, - 0xAF, 0xCF, 0x8C, 0xCF, 0x8D, 0xCF, 0x8E, 0xCE, - 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, 0xCE, 0xB4, 0xCE, - 0xB5, 0xCE, 0xB6, 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, - 0xB9, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xBC, 0xCE, - 0xBD, 0xCE, 0xBE, 0xCE, 0xBF, 0xCF, 0x80, 0xCF, - 0x81, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x85, 0xCF, - 0x86, 0xCF, 0x87, 0xCF, 0x88, 0xCF, 0x89, 0xCF, - 0x8A, 0xCF, 0x8B, 0xCF, 0x99, 0xCF, 0x9B, 0xCF, - 0x9D, 0xCF, 0x9F, 0xCF, 0xA1, 0xCF, 0xA3, 0xCF, - 0xA5, 0xCF, 0xA7, 0xCF, 0xA9, 0xCF, 0xAB, 0xCF, - 0xAD, 0xCF, 0xAF, 0xCE, 0xB8, 0xCF, 0xB8, 0xCF, - 0xB2, 0xCF, 0xBB, 0xCD, 0xBB, 0xCD, 0xBC, 0xCD, - 0xBD, 0xD1, 0x90, 0xD1, 0x91, 0xD1, 0x92, 0xD1, - 0x93, 0xD1, 0x94, 0xD1, 0x95, 0xD1, 0x96, 0xD1, - 0x97, 0xD1, 0x98, 0xD1, 0x99, 0xD1, 0x9A, 0xD1, - 0x9B, 0xD1, 0x9C, 0xD1, 0x9D, 0xD1, 0x9E, 0xD1, - 0x9F, 0xD0, 0xB0, 0xD0, 0xB1, 0xD0, 0xB2, 0xD0, - 0xB3, 0xD0, 0xB4, 0xD0, 0xB5, 0xD0, 0xB6, 0xD0, - 0xB7, 0xD0, 0xB8, 0xD0, 0xB9, 0xD0, 0xBA, 0xD0, - 0xBB, 0xD0, 0xBC, 0xD0, 0xBD, 0xD0, 0xBE, 0xD0, - 0xBF, 0xD1, 0x80, 0xD1, 0x81, 0xD1, 0x82, 0xD1, - 0x83, 0xD1, 0x84, 0xD1, 0x85, 0xD1, 0x86, 0xD1, - 0x87, 0xD1, 0x88, 0xD1, 0x89, 0xD1, 0x8A, 0xD1, - 0x8B, 0xD1, 0x8C, 0xD1, 0x8D, 0xD1, 0x8E, 0xD1, - 0x8F, 0xD1, 0xA1, 0xD1, 0xA3, 0xD1, 0xA5, 0xD1, - 0xA7, 0xD1, 0xA9, 0xD1, 0xAB, 0xD1, 0xAD, 0xD1, - 0xAF, 0xD1, 0xB1, 0xD1, 0xB3, 0xD1, 0xB5, 0xD1, - 0xB7, 0xD1, 0xB9, 0xD1, 0xBB, 0xD1, 0xBD, 0xD1, - 0xBF, 0xD2, 0x81, 0xD2, 0x8B, 0xD2, 0x8D, 0xD2, - 0x8F, 0xD2, 0x91, 0xD2, 0x93, 0xD2, 0x95, 0xD2, - 0x97, 0xD2, 0x99, 0xD2, 0x9B, 0xD2, 0x9D, 0xD2, - 0x9F, 0xD2, 0xA1, 0xD2, 0xA3, 0xD2, 0xA5, 0xD2, - 0xA7, 0xD2, 0xA9, 0xD2, 0xAB, 0xD2, 0xAD, 0xD2, - 0xAF, 0xD2, 0xB1, 0xD2, 0xB3, 0xD2, 0xB5, 0xD2, - 0xB7, 0xD2, 0xB9, 0xD2, 0xBB, 0xD2, 0xBD, 0xD2, - 0xBF, 0xD3, 0x8F, 0xD3, 0x82, 0xD3, 0x84, 0xD3, - 0x86, 0xD3, 0x88, 0xD3, 0x8A, 0xD3, 0x8C, 0xD3, - 0x8E, 0xD3, 0x91, 0xD3, 0x93, 0xD3, 0x95, 0xD3, - 0x97, 0xD3, 0x99, 0xD3, 0x9B, 0xD3, 0x9D, 0xD3, - 0x9F, 0xD3, 0xA1, 0xD3, 0xA3, 0xD3, 0xA5, 0xD3, - 0xA7, 0xD3, 0xA9, 0xD3, 0xAB, 0xD3, 0xAD, 0xD3, - 0xAF, 0xD3, 0xB1, 0xD3, 0xB3, 0xD3, 0xB5, 0xD3, - 0xB7, 0xD3, 0xB9, 0xD3, 0xBB, 0xD3, 0xBD, 0xD3, - 0xBF, 0xD4, 0x81, 0xD4, 0x83, 0xD4, 0x85, 0xD4, - 0x87, 0xD4, 0x89, 0xD4, 0x8B, 0xD4, 0x8D, 0xD4, - 0x8F, 0xD4, 0x91, 0xD4, 0x93, 0xD5, 0xA1, 0xD5, - 0xA2, 0xD5, 0xA3, 0xD5, 0xA4, 0xD5, 0xA5, 0xD5, - 0xA6, 0xD5, 0xA7, 0xD5, 0xA8, 0xD5, 0xA9, 0xD5, - 0xAA, 0xD5, 0xAB, 0xD5, 0xAC, 0xD5, 0xAD, 0xD5, - 0xAE, 0xD5, 0xAF, 0xD5, 0xB0, 0xD5, 0xB1, 0xD5, - 0xB2, 0xD5, 0xB3, 0xD5, 0xB4, 0xD5, 0xB5, 0xD5, - 0xB6, 0xD5, 0xB7, 0xD5, 0xB8, 0xD5, 0xB9, 0xD5, - 0xBA, 0xD5, 0xBB, 0xD5, 0xBC, 0xD5, 0xBD, 0xD5, - 0xBE, 0xD5, 0xBF, 0xD6, 0x80, 0xD6, 0x81, 0xD6, - 0x82, 0xD6, 0x83, 0xD6, 0x84, 0xD6, 0x85, 0xD6, - 0x86, 0xE2, 0xB4, 0x80, 0xE2, 0xB4, 0x81, 0xE2, - 0xB4, 0x82, 0xE2, 0xB4, 0x83, 0xE2, 0xB4, 0x84, - 0xE2, 0xB4, 0x85, 0xE2, 0xB4, 0x86, 0xE2, 0xB4, - 0x87, 0xE2, 0xB4, 0x88, 0xE2, 0xB4, 0x89, 0xE2, - 0xB4, 0x8A, 0xE2, 0xB4, 0x8B, 0xE2, 0xB4, 0x8C, - 0xE2, 0xB4, 0x8D, 0xE2, 0xB4, 0x8E, 0xE2, 0xB4, - 0x8F, 0xE2, 0xB4, 0x90, 0xE2, 0xB4, 0x91, 0xE2, - 0xB4, 0x92, 0xE2, 0xB4, 0x93, 0xE2, 0xB4, 0x94, - 0xE2, 0xB4, 0x95, 0xE2, 0xB4, 0x96, 0xE2, 0xB4, - 0x97, 0xE2, 0xB4, 0x98, 0xE2, 0xB4, 0x99, 0xE2, - 0xB4, 0x9A, 0xE2, 0xB4, 0x9B, 0xE2, 0xB4, 0x9C, - 0xE2, 0xB4, 0x9D, 0xE2, 0xB4, 0x9E, 0xE2, 0xB4, - 0x9F, 0xE2, 0xB4, 0xA0, 0xE2, 0xB4, 0xA1, 0xE2, - 0xB4, 0xA2, 0xE2, 0xB4, 0xA3, 0xE2, 0xB4, 0xA4, - 0xE2, 0xB4, 0xA5, 0xE1, 0xB8, 0x81, 0xE1, 0xB8, - 0x83, 0xE1, 0xB8, 0x85, 0xE1, 0xB8, 0x87, 0xE1, - 0xB8, 0x89, 0xE1, 0xB8, 0x8B, 0xE1, 0xB8, 0x8D, - 0xE1, 0xB8, 0x8F, 0xE1, 0xB8, 0x91, 0xE1, 0xB8, - 0x93, 0xE1, 0xB8, 0x95, 0xE1, 0xB8, 0x97, 0xE1, - 0xB8, 0x99, 0xE1, 0xB8, 0x9B, 0xE1, 0xB8, 0x9D, - 0xE1, 0xB8, 0x9F, 0xE1, 0xB8, 0xA1, 0xE1, 0xB8, - 0xA3, 0xE1, 0xB8, 0xA5, 0xE1, 0xB8, 0xA7, 0xE1, - 0xB8, 0xA9, 0xE1, 0xB8, 0xAB, 0xE1, 0xB8, 0xAD, - 0xE1, 0xB8, 0xAF, 0xE1, 0xB8, 0xB1, 0xE1, 0xB8, - 0xB3, 0xE1, 0xB8, 0xB5, 0xE1, 0xB8, 0xB7, 0xE1, - 0xB8, 0xB9, 0xE1, 0xB8, 0xBB, 0xE1, 0xB8, 0xBD, - 0xE1, 0xB8, 0xBF, 0xE1, 0xB9, 0x81, 0xE1, 0xB9, - 0x83, 0xE1, 0xB9, 0x85, 0xE1, 0xB9, 0x87, 0xE1, - 0xB9, 0x89, 0xE1, 0xB9, 0x8B, 0xE1, 0xB9, 0x8D, - 0xE1, 0xB9, 0x8F, 0xE1, 0xB9, 0x91, 0xE1, 0xB9, - 0x93, 0xE1, 0xB9, 0x95, 0xE1, 0xB9, 0x97, 0xE1, - 0xB9, 0x99, 0xE1, 0xB9, 0x9B, 0xE1, 0xB9, 0x9D, - 0xE1, 0xB9, 0x9F, 0xE1, 0xB9, 0xA1, 0xE1, 0xB9, - 0xA3, 0xE1, 0xB9, 0xA5, 0xE1, 0xB9, 0xA7, 0xE1, - 0xB9, 0xA9, 0xE1, 0xB9, 0xAB, 0xE1, 0xB9, 0xAD, - 0xE1, 0xB9, 0xAF, 0xE1, 0xB9, 0xB1, 0xE1, 0xB9, - 0xB3, 0xE1, 0xB9, 0xB5, 0xE1, 0xB9, 0xB7, 0xE1, - 0xB9, 0xB9, 0xE1, 0xB9, 0xBB, 0xE1, 0xB9, 0xBD, - 0xE1, 0xB9, 0xBF, 0xE1, 0xBA, 0x81, 0xE1, 0xBA, - 0x83, 0xE1, 0xBA, 0x85, 0xE1, 0xBA, 0x87, 0xE1, - 0xBA, 0x89, 0xE1, 0xBA, 0x8B, 0xE1, 0xBA, 0x8D, - 0xE1, 0xBA, 0x8F, 0xE1, 0xBA, 0x91, 0xE1, 0xBA, - 0x93, 0xE1, 0xBA, 0x95, 0xE1, 0xBA, 0xA1, 0xE1, - 0xBA, 0xA3, 0xE1, 0xBA, 0xA5, 0xE1, 0xBA, 0xA7, - 0xE1, 0xBA, 0xA9, 0xE1, 0xBA, 0xAB, 0xE1, 0xBA, - 0xAD, 0xE1, 0xBA, 0xAF, 0xE1, 0xBA, 0xB1, 0xE1, - 0xBA, 0xB3, 0xE1, 0xBA, 0xB5, 0xE1, 0xBA, 0xB7, - 0xE1, 0xBA, 0xB9, 0xE1, 0xBA, 0xBB, 0xE1, 0xBA, - 0xBD, 0xE1, 0xBA, 0xBF, 0xE1, 0xBB, 0x81, 0xE1, - 0xBB, 0x83, 0xE1, 0xBB, 0x85, 0xE1, 0xBB, 0x87, - 0xE1, 0xBB, 0x89, 0xE1, 0xBB, 0x8B, 0xE1, 0xBB, - 0x8D, 0xE1, 0xBB, 0x8F, 0xE1, 0xBB, 0x91, 0xE1, - 0xBB, 0x93, 0xE1, 0xBB, 0x95, 0xE1, 0xBB, 0x97, - 0xE1, 0xBB, 0x99, 0xE1, 0xBB, 0x9B, 0xE1, 0xBB, - 0x9D, 0xE1, 0xBB, 0x9F, 0xE1, 0xBB, 0xA1, 0xE1, - 0xBB, 0xA3, 0xE1, 0xBB, 0xA5, 0xE1, 0xBB, 0xA7, - 0xE1, 0xBB, 0xA9, 0xE1, 0xBB, 0xAB, 0xE1, 0xBB, - 0xAD, 0xE1, 0xBB, 0xAF, 0xE1, 0xBB, 0xB1, 0xE1, - 0xBB, 0xB3, 0xE1, 0xBB, 0xB5, 0xE1, 0xBB, 0xB7, - 0xE1, 0xBB, 0xB9, 0xE1, 0xBC, 0x80, 0xE1, 0xBC, - 0x81, 0xE1, 0xBC, 0x82, 0xE1, 0xBC, 0x83, 0xE1, - 0xBC, 0x84, 0xE1, 0xBC, 0x85, 0xE1, 0xBC, 0x86, - 0xE1, 0xBC, 0x87, 0xE1, 0xBC, 0x90, 0xE1, 0xBC, - 0x91, 0xE1, 0xBC, 0x92, 0xE1, 0xBC, 0x93, 0xE1, - 0xBC, 0x94, 0xE1, 0xBC, 0x95, 0xE1, 0xBC, 0xA0, - 0xE1, 0xBC, 0xA1, 0xE1, 0xBC, 0xA2, 0xE1, 0xBC, - 0xA3, 0xE1, 0xBC, 0xA4, 0xE1, 0xBC, 0xA5, 0xE1, - 0xBC, 0xA6, 0xE1, 0xBC, 0xA7, 0xE1, 0xBC, 0xB0, - 0xE1, 0xBC, 0xB1, 0xE1, 0xBC, 0xB2, 0xE1, 0xBC, - 0xB3, 0xE1, 0xBC, 0xB4, 0xE1, 0xBC, 0xB5, 0xE1, - 0xBC, 0xB6, 0xE1, 0xBC, 0xB7, 0xE1, 0xBD, 0x80, - 0xE1, 0xBD, 0x81, 0xE1, 0xBD, 0x82, 0xE1, 0xBD, - 0x83, 0xE1, 0xBD, 0x84, 0xE1, 0xBD, 0x85, 0xE1, - 0xBD, 0x91, 0xE1, 0xBD, 0x93, 0xE1, 0xBD, 0x95, - 0xE1, 0xBD, 0x97, 0xE1, 0xBD, 0xA0, 0xE1, 0xBD, - 0xA1, 0xE1, 0xBD, 0xA2, 0xE1, 0xBD, 0xA3, 0xE1, - 0xBD, 0xA4, 0xE1, 0xBD, 0xA5, 0xE1, 0xBD, 0xA6, - 0xE1, 0xBD, 0xA7, 0xE1, 0xBE, 0x80, 0xE1, 0xBE, - 0x81, 0xE1, 0xBE, 0x82, 0xE1, 0xBE, 0x83, 0xE1, - 0xBE, 0x84, 0xE1, 0xBE, 0x85, 0xE1, 0xBE, 0x86, - 0xE1, 0xBE, 0x87, 0xE1, 0xBE, 0x90, 0xE1, 0xBE, - 0x91, 0xE1, 0xBE, 0x92, 0xE1, 0xBE, 0x93, 0xE1, - 0xBE, 0x94, 0xE1, 0xBE, 0x95, 0xE1, 0xBE, 0x96, - 0xE1, 0xBE, 0x97, 0xE1, 0xBE, 0xA0, 0xE1, 0xBE, - 0xA1, 0xE1, 0xBE, 0xA2, 0xE1, 0xBE, 0xA3, 0xE1, - 0xBE, 0xA4, 0xE1, 0xBE, 0xA5, 0xE1, 0xBE, 0xA6, - 0xE1, 0xBE, 0xA7, 0xE1, 0xBE, 0xB0, 0xE1, 0xBE, - 0xB1, 0xE1, 0xBD, 0xB0, 0xE1, 0xBD, 0xB1, 0xE1, - 0xBE, 0xB3, 0xE1, 0xBD, 0xB2, 0xE1, 0xBD, 0xB3, - 0xE1, 0xBD, 0xB4, 0xE1, 0xBD, 0xB5, 0xE1, 0xBF, - 0x83, 0xE1, 0xBF, 0x90, 0xE1, 0xBF, 0x91, 0xE1, - 0xBD, 0xB6, 0xE1, 0xBD, 0xB7, 0xE1, 0xBF, 0xA0, - 0xE1, 0xBF, 0xA1, 0xE1, 0xBD, 0xBA, 0xE1, 0xBD, - 0xBB, 0xE1, 0xBF, 0xA5, 0xE1, 0xBD, 0xB8, 0xE1, - 0xBD, 0xB9, 0xE1, 0xBD, 0xBC, 0xE1, 0xBD, 0xBD, - 0xE1, 0xBF, 0xB3, 0xCF, 0x89, 0x6B, 0xC3, 0xA5, - 0xE2, 0x85, 0x8E, 0xE2, 0x85, 0xB0, 0xE2, 0x85, - 0xB1, 0xE2, 0x85, 0xB2, 0xE2, 0x85, 0xB3, 0xE2, - 0x85, 0xB4, 0xE2, 0x85, 0xB5, 0xE2, 0x85, 0xB6, - 0xE2, 0x85, 0xB7, 0xE2, 0x85, 0xB8, 0xE2, 0x85, - 0xB9, 0xE2, 0x85, 0xBA, 0xE2, 0x85, 0xBB, 0xE2, - 0x85, 0xBC, 0xE2, 0x85, 0xBD, 0xE2, 0x85, 0xBE, - 0xE2, 0x85, 0xBF, 0xE2, 0x86, 0x84, 0xE2, 0x93, - 0x90, 0xE2, 0x93, 0x91, 0xE2, 0x93, 0x92, 0xE2, - 0x93, 0x93, 0xE2, 0x93, 0x94, 0xE2, 0x93, 0x95, - 0xE2, 0x93, 0x96, 0xE2, 0x93, 0x97, 0xE2, 0x93, - 0x98, 0xE2, 0x93, 0x99, 0xE2, 0x93, 0x9A, 0xE2, - 0x93, 0x9B, 0xE2, 0x93, 0x9C, 0xE2, 0x93, 0x9D, - 0xE2, 0x93, 0x9E, 0xE2, 0x93, 0x9F, 0xE2, 0x93, - 0xA0, 0xE2, 0x93, 0xA1, 0xE2, 0x93, 0xA2, 0xE2, - 0x93, 0xA3, 0xE2, 0x93, 0xA4, 0xE2, 0x93, 0xA5, - 0xE2, 0x93, 0xA6, 0xE2, 0x93, 0xA7, 0xE2, 0x93, - 0xA8, 0xE2, 0x93, 0xA9, 0xE2, 0xB0, 0xB0, 0xE2, - 0xB0, 0xB1, 0xE2, 0xB0, 0xB2, 0xE2, 0xB0, 0xB3, - 0xE2, 0xB0, 0xB4, 0xE2, 0xB0, 0xB5, 0xE2, 0xB0, - 0xB6, 0xE2, 0xB0, 0xB7, 0xE2, 0xB0, 0xB8, 0xE2, - 0xB0, 0xB9, 0xE2, 0xB0, 0xBA, 0xE2, 0xB0, 0xBB, - 0xE2, 0xB0, 0xBC, 0xE2, 0xB0, 0xBD, 0xE2, 0xB0, - 0xBE, 0xE2, 0xB0, 0xBF, 0xE2, 0xB1, 0x80, 0xE2, - 0xB1, 0x81, 0xE2, 0xB1, 0x82, 0xE2, 0xB1, 0x83, - 0xE2, 0xB1, 0x84, 0xE2, 0xB1, 0x85, 0xE2, 0xB1, - 0x86, 0xE2, 0xB1, 0x87, 0xE2, 0xB1, 0x88, 0xE2, - 0xB1, 0x89, 0xE2, 0xB1, 0x8A, 0xE2, 0xB1, 0x8B, - 0xE2, 0xB1, 0x8C, 0xE2, 0xB1, 0x8D, 0xE2, 0xB1, - 0x8E, 0xE2, 0xB1, 0x8F, 0xE2, 0xB1, 0x90, 0xE2, - 0xB1, 0x91, 0xE2, 0xB1, 0x92, 0xE2, 0xB1, 0x93, - 0xE2, 0xB1, 0x94, 0xE2, 0xB1, 0x95, 0xE2, 0xB1, - 0x96, 0xE2, 0xB1, 0x97, 0xE2, 0xB1, 0x98, 0xE2, - 0xB1, 0x99, 0xE2, 0xB1, 0x9A, 0xE2, 0xB1, 0x9B, - 0xE2, 0xB1, 0x9C, 0xE2, 0xB1, 0x9D, 0xE2, 0xB1, - 0x9E, 0xE2, 0xB1, 0xA1, 0xC9, 0xAB, 0xE1, 0xB5, - 0xBD, 0xC9, 0xBD, 0xE2, 0xB1, 0xA8, 0xE2, 0xB1, - 0xAA, 0xE2, 0xB1, 0xAC, 0xE2, 0xB1, 0xB6, 0xE2, - 0xB2, 0x81, 0xE2, 0xB2, 0x83, 0xE2, 0xB2, 0x85, - 0xE2, 0xB2, 0x87, 0xE2, 0xB2, 0x89, 0xE2, 0xB2, - 0x8B, 0xE2, 0xB2, 0x8D, 0xE2, 0xB2, 0x8F, 0xE2, - 0xB2, 0x91, 0xE2, 0xB2, 0x93, 0xE2, 0xB2, 0x95, - 0xE2, 0xB2, 0x97, 0xE2, 0xB2, 0x99, 0xE2, 0xB2, - 0x9B, 0xE2, 0xB2, 0x9D, 0xE2, 0xB2, 0x9F, 0xE2, - 0xB2, 0xA1, 0xE2, 0xB2, 0xA3, 0xE2, 0xB2, 0xA5, - 0xE2, 0xB2, 0xA7, 0xE2, 0xB2, 0xA9, 0xE2, 0xB2, - 0xAB, 0xE2, 0xB2, 0xAD, 0xE2, 0xB2, 0xAF, 0xE2, - 0xB2, 0xB1, 0xE2, 0xB2, 0xB3, 0xE2, 0xB2, 0xB5, - 0xE2, 0xB2, 0xB7, 0xE2, 0xB2, 0xB9, 0xE2, 0xB2, - 0xBB, 0xE2, 0xB2, 0xBD, 0xE2, 0xB2, 0xBF, 0xE2, - 0xB3, 0x81, 0xE2, 0xB3, 0x83, 0xE2, 0xB3, 0x85, - 0xE2, 0xB3, 0x87, 0xE2, 0xB3, 0x89, 0xE2, 0xB3, - 0x8B, 0xE2, 0xB3, 0x8D, 0xE2, 0xB3, 0x8F, 0xE2, - 0xB3, 0x91, 0xE2, 0xB3, 0x93, 0xE2, 0xB3, 0x95, - 0xE2, 0xB3, 0x97, 0xE2, 0xB3, 0x99, 0xE2, 0xB3, - 0x9B, 0xE2, 0xB3, 0x9D, 0xE2, 0xB3, 0x9F, 0xE2, - 0xB3, 0xA1, 0xE2, 0xB3, 0xA3, 0xEF, 0xBD, 0x81, - 0xEF, 0xBD, 0x82, 0xEF, 0xBD, 0x83, 0xEF, 0xBD, - 0x84, 0xEF, 0xBD, 0x85, 0xEF, 0xBD, 0x86, 0xEF, - 0xBD, 0x87, 0xEF, 0xBD, 0x88, 0xEF, 0xBD, 0x89, - 0xEF, 0xBD, 0x8A, 0xEF, 0xBD, 0x8B, 0xEF, 0xBD, - 0x8C, 0xEF, 0xBD, 0x8D, 0xEF, 0xBD, 0x8E, 0xEF, - 0xBD, 0x8F, 0xEF, 0xBD, 0x90, 0xEF, 0xBD, 0x91, - 0xEF, 0xBD, 0x92, 0xEF, 0xBD, 0x93, 0xEF, 0xBD, - 0x94, 0xEF, 0xBD, 0x95, 0xEF, 0xBD, 0x96, 0xEF, - 0xBD, 0x97, 0xEF, 0xBD, 0x98, 0xEF, 0xBD, 0x99, - 0xEF, 0xBD, 0x9A, 0xF0, 0x90, 0x90, 0xA8, 0xF0, - 0x90, 0x90, 0xA9, 0xF0, 0x90, 0x90, 0xAA, 0xF0, - 0x90, 0x90, 0xAB, 0xF0, 0x90, 0x90, 0xAC, 0xF0, - 0x90, 0x90, 0xAD, 0xF0, 0x90, 0x90, 0xAE, 0xF0, - 0x90, 0x90, 0xAF, 0xF0, 0x90, 0x90, 0xB0, 0xF0, - 0x90, 0x90, 0xB1, 0xF0, 0x90, 0x90, 0xB2, 0xF0, - 0x90, 0x90, 0xB3, 0xF0, 0x90, 0x90, 0xB4, 0xF0, - 0x90, 0x90, 0xB5, 0xF0, 0x90, 0x90, 0xB6, 0xF0, - 0x90, 0x90, 0xB7, 0xF0, 0x90, 0x90, 0xB8, 0xF0, - 0x90, 0x90, 0xB9, 0xF0, 0x90, 0x90, 0xBA, 0xF0, - 0x90, 0x90, 0xBB, 0xF0, 0x90, 0x90, 0xBC, 0xF0, - 0x90, 0x90, 0xBD, 0xF0, 0x90, 0x90, 0xBE, 0xF0, - 0x90, 0x90, 0xBF, 0xF0, 0x90, 0x91, 0x80, 0xF0, - 0x90, 0x91, 0x81, 0xF0, 0x90, 0x91, 0x82, 0xF0, - 0x90, 0x91, 0x83, 0xF0, 0x90, 0x91, 0x84, 0xF0, - 0x90, 0x91, 0x85, 0xF0, 0x90, 0x91, 0x86, 0xF0, - 0x90, 0x91, 0x87, 0xF0, 0x90, 0x91, 0x88, 0xF0, - 0x90, 0x91, 0x89, 0xF0, 0x90, 0x91, 0x8A, 0xF0, - 0x90, 0x91, 0x8B, 0xF0, 0x90, 0x91, 0x8C, 0xF0, - 0x90, 0x91, 0x8D, 0xF0, 0x90, 0x91, 0x8E, 0xF0, - 0x90, 0x91, 0x8F, - }, -}; - -static const u8_displacement_t u8_toupper_b3_tbl[2][5][256] = { - { - { /* Third byte table 0. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0, 0 }, { 1, 2 }, - { 2, 64 }, { 3, 125 }, { 4, 188 }, { 5, 226 }, - { 6, 288 }, { 7, 338 }, { 8, 364 }, { N_, 0 }, - { N_, 0 }, { 9, 376 }, { 10, 378 }, { 11, 416 }, - { 12, 486 }, { 13, 518 }, { 14, 614 }, { 15, 670 }, - { 16, 724 }, { 17, 740 }, { 18, 802 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 1. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 19, 816 }, { 20, 912 }, { 21, 1008 }, { 22, 1092 }, - { 23, 1179 }, { 24, 1269 }, { 25, 1365 }, { 26, 1448 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 2. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 27, 1469 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { 28, 1517 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 3. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 29, 1595 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 4. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 30, 1673 }, { 31, 1769 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - }, - { - { /* Third byte table 0. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { 0, 0 }, { 1, 2 }, - { 2, 64 }, { 3, 125 }, { 4, 188 }, { 5, 230 }, - { 6, 292 }, { 7, 344 }, { 8, 388 }, { N_, 0 }, - { N_, 0 }, { 9, 404 }, { 10, 412 }, { 11, 450 }, - { 12, 524 }, { 13, 556 }, { 14, 652 }, { 15, 708 }, - { 16, 772 }, { 17, 792 }, { 18, 854 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 1. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 19, 868 }, { N_, 0 }, { N_, 0 }, - { 20, 871 }, { 21, 967 }, { 22, 1063 }, { 23, 1147 }, - { 24, 1234 }, { 25, 1324 }, { 26, 1420 }, { 27, 1503 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 2. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 28, 1524 }, { 29, 1575 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { 30, 1578 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 31, 1656 }, { 32, 1704 }, { 33, 1816 }, { 34, 1912 }, - { 35, 1966 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 3. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { 36, 2080 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - { /* Third byte table 4. */ - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { 37, 2158 }, { 38, 2254 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - { N_, 0 }, { N_, 0 }, { N_, 0 }, { N_, 0 }, - }, - }, -}; - -static const uchar_t u8_toupper_b4_tbl[2][39][257] = { - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 46, 48, 50, 52, 54, 56, 58, 60, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 49, 49, 51, 51, 53, 53, - 55, 55, 55, 57, 57, 59, 59, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 50, 50, 52, 52, 54, 54, - 56, 56, 56, 58, 58, 60, 60, 62, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 2, 4, 4, - 4, 6, 6, 6, 6, 8, 8, 8, - 8, 8, 8, 10, 10, 10, 12, 12, - 12, 12, 14, 14, 14, 14, 14, 16, - 16, 16, 18, 18, 20, 20, 22, 22, - 22, 24, 24, 24, 24, 24, 26, 26, - 26, 28, 28, 28, 28, 30, 30, 32, - 32, 32, 34, 34, 34, 34, 36, 36, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 4, - 4, 6, 8, 8, 10, 12, 12, 14, - 14, 16, 16, 18, 18, 20, 20, 22, - 22, 24, 24, 26, 26, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 48, 50, 52, 52, 54, 54, - 54, 54, 56, 56, 58, 58, 60, 60, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 32, 32, 34, 34, 36, 36, - 38, 38, 40, 40, 42, 42, 44, 44, - 46, 46, 48, 48, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 4, 4, 6, - 8, 8, 10, 10, 12, 12, 12, 12, - 12, 14, 14, 14, 16, 16, 16, 16, - 16, 18, 20, 20, 20, 20, 20, 20, - 22, 22, 22, 24, 24, 24, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 4, 4, 4, 4, - 4, 6, 6, 8, 10, 10, 10, 10, - 10, 10, 10, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 4, 6, - 8, 8, 10, 12, 14, 16, 18, 20, - 22, 24, 26, 28, 30, 32, 34, 36, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 30, 32, 34, 34, 34, 34, 36, 38, - 38, 38, 40, 40, 42, 42, 44, 44, - 46, 46, 48, 48, 50, 50, 52, 52, - 54, 54, 56, 56, 58, 58, 60, 60, - 62, 64, 66, 68, 68, 68, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - 64, 64, 66, 66, 68, 68, 70, 70, - 72, 72, 74, 74, 76, 76, 78, 78, - 80, 80, 82, 82, 84, 84, 86, 86, - 88, 88, 90, 90, 92, 92, 94, 94, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 50, 50, 52, 52, 54, 54, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 2, 4, 4, 6, - 6, 8, 8, 10, 10, 12, 12, 14, - 14, 14, 16, 16, 18, 18, 20, 20, - 22, 22, 24, 24, 26, 26, 28, 28, - 30, 30, 32, 32, 34, 34, 36, 36, - 38, 38, 40, 40, 42, 42, 44, 44, - 46, 46, 48, 48, 50, 50, 52, 52, - 52, 52, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 4, 6, 8, 10, 12, - 14, 16, 18, 20, 22, 24, 26, 28, - 30, 32, 34, 36, 38, 40, 42, 44, - 46, 48, 50, 52, 54, 56, 58, 60, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 87, 87, 90, 90, 93, 93, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 87, 87, 90, 90, 93, 93, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 33, 33, 33, 33, 36, 36, 36, 36, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 27, 30, 33, 36, 39, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 45, 48, 51, 54, 57, 60, 63, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 69, 72, 75, 78, 81, 84, 87, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 21, 21, 24, 24, 27, 27, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 33, 36, 39, 42, 45, 48, 51, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 57, 60, 63, 66, 69, 72, 75, - 78, 81, 84, 87, 90, 93, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 75, 78, 78, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 6, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 12, 15, 15, 15, 15, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 6, 9, 12, 15, 18, - 21, 24, 27, 30, 33, 36, 39, 42, - 45, 48, 51, 54, 57, 60, 63, 66, - 69, 72, 75, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 36. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 37. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - { /* Fourth byte table 38. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - }, - }, - { - { /* Fourth byte table 0. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, - }, - { /* Fourth byte table 1. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 46, 48, 50, 52, 54, 56, 58, 60, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 2. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 49, 49, 51, 51, 53, 53, - 55, 55, 55, 57, 57, 59, 59, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, - }, - { /* Fourth byte table 3. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 4, 4, 6, 6, 8, - 8, 10, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 50, 50, 52, 52, 54, 54, - 56, 56, 56, 58, 58, 60, 60, 62, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, - }, - { /* Fourth byte table 4. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 4, 4, 6, 6, - 6, 8, 8, 8, 8, 10, 10, 10, - 10, 10, 10, 12, 12, 12, 14, 14, - 14, 14, 16, 18, 18, 18, 18, 20, - 20, 20, 22, 22, 24, 24, 26, 26, - 26, 28, 28, 28, 28, 28, 30, 30, - 30, 32, 32, 32, 32, 34, 34, 36, - 36, 36, 38, 38, 38, 38, 40, 40, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, - }, - { /* Fourth byte table 5. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 4, - 4, 6, 8, 8, 10, 12, 12, 14, - 14, 16, 16, 18, 18, 20, 20, 22, - 22, 24, 24, 26, 26, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 48, 50, 52, 52, 54, 54, - 54, 54, 56, 56, 58, 58, 60, 60, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 6. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 32, 32, 34, 34, 36, 36, - 38, 38, 40, 40, 42, 42, 44, 44, - 46, 46, 48, 48, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, - }, - { /* Fourth byte table 7. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 2, 2, - 4, 4, 6, 6, 8, 8, 10, 10, - 12, 12, 12, 12, 14, 16, 16, 18, - 20, 20, 22, 22, 24, 24, 24, 24, - 24, 26, 26, 26, 28, 28, 28, 28, - 28, 30, 32, 32, 35, 35, 35, 35, - 37, 37, 37, 39, 39, 39, 41, 41, - 41, 41, 41, 41, 41, 41, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, - }, - { /* Fourth byte table 8. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 4, 4, 4, 4, - 4, 6, 8, 10, 12, 14, 14, 14, - 14, 14, 14, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - }, - { /* Fourth byte table 9. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 4, 6, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, - }, - { /* Fourth byte table 10. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 4, 6, - 8, 8, 10, 12, 14, 16, 18, 20, - 22, 24, 26, 28, 30, 32, 34, 36, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, - }, - { /* Fourth byte table 11. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 30, 32, 34, 34, 34, 34, 36, 38, - 38, 38, 40, 40, 42, 42, 44, 44, - 46, 46, 48, 48, 50, 50, 52, 52, - 54, 54, 56, 56, 58, 58, 60, 60, - 62, 64, 66, 68, 68, 68, 70, 70, - 70, 72, 72, 72, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, - }, - { /* Fourth byte table 12. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, - }, - { /* Fourth byte table 13. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - 64, 64, 66, 66, 68, 68, 70, 70, - 72, 72, 74, 74, 76, 76, 78, 78, - 80, 80, 82, 82, 84, 84, 86, 86, - 88, 88, 90, 90, 92, 92, 94, 94, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 14. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 50, 50, 52, 52, 54, 54, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, - }, - { /* Fourth byte table 15. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 2, 4, 4, 6, - 6, 8, 8, 10, 10, 12, 12, 14, - 16, 16, 18, 18, 20, 20, 22, 22, - 24, 24, 26, 26, 28, 28, 30, 30, - 32, 32, 34, 34, 36, 36, 38, 38, - 40, 40, 42, 42, 44, 44, 46, 46, - 48, 48, 50, 50, 52, 52, 54, 54, - 56, 56, 58, 58, 60, 60, 62, 62, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - { /* Fourth byte table 16. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 4, 4, 6, 6, - 8, 8, 10, 10, 12, 12, 14, 14, - 16, 16, 18, 18, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, - }, - { /* Fourth byte table 17. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 4, 6, 8, 10, 12, - 14, 16, 18, 20, 22, 24, 26, 28, - 30, 32, 34, 36, 38, 40, 42, 44, - 46, 48, 50, 52, 54, 56, 58, 60, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 62, - }, - { /* Fourth byte table 18. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 4, 6, 8, 10, 12, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { /* Fourth byte table 19. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 20. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 87, 87, 90, 90, 93, 93, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 21. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 87, 87, 90, 90, 93, 93, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 22. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 33, 33, 33, 33, 36, 36, 36, 36, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, - }, - { /* Fourth byte table 23. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, - 87, - }, - { /* Fourth byte table 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 27, 30, 33, 36, 39, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 45, 48, 51, 54, 57, 60, 63, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 69, 72, 75, 78, 81, 84, 87, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, - }, - { /* Fourth byte table 25. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 21, 21, 24, 24, 27, 27, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 33, 36, 39, 42, 45, 48, 51, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 57, 60, 63, 66, 69, 72, 75, - 78, 81, 84, 87, 90, 93, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 26. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 24, 24, 24, 24, 24, 24, 24, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 75, 78, 78, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, - }, - { /* Fourth byte table 27. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 6, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 12, 15, 15, 15, 15, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, - }, - { /* Fourth byte table 28. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 6, 9, 12, 15, 18, 21, 24, - 27, 30, 33, 36, 39, 42, 45, 48, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, - }, - { /* Fourth byte table 29. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, - }, - { /* Fourth byte table 30. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, - }, - { /* Fourth byte table 31. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, - }, - { /* Fourth byte table 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 93, 93, 96, 96, 96, 96, 98, 100, - 100, 103, 103, 106, 106, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, - 112, - }, - { /* Fourth byte table 33. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 57, 57, - 60, 60, 63, 63, 66, 66, 69, 69, - 72, 72, 75, 75, 78, 78, 81, 81, - 84, 84, 87, 87, 90, 90, 93, 93, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 34. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 6, 6, 9, 9, - 12, 12, 15, 15, 18, 18, 21, 21, - 24, 24, 27, 27, 30, 30, 33, 33, - 36, 36, 39, 39, 42, 42, 45, 45, - 48, 48, 51, 51, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, - 54, - }, - { /* Fourth byte table 35. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, 9, 12, 15, 18, 21, - 24, 27, 30, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, - 72, 75, 78, 81, 84, 87, 90, 93, - 96, 99, 102, 105, 108, 111, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, - }, - { /* Fourth byte table 36. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 6, 9, 12, 15, 18, - 21, 24, 27, 30, 33, 36, 39, 42, - 45, 48, 51, 54, 57, 60, 63, 66, - 69, 72, 75, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, - }, - { /* Fourth byte table 37. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, - }, - { /* Fourth byte table 38. */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, - }, - }, -}; - -static const uchar_t u8_toupper_final_tbl[2][2318] = { - { - 0xCE, 0x9C, 0xC3, 0x80, 0xC3, 0x81, 0xC3, 0x82, - 0xC3, 0x83, 0xC3, 0x84, 0xC3, 0x85, 0xC3, 0x86, - 0xC3, 0x87, 0xC3, 0x88, 0xC3, 0x89, 0xC3, 0x8A, - 0xC3, 0x8B, 0xC3, 0x8C, 0xC3, 0x8D, 0xC3, 0x8E, - 0xC3, 0x8F, 0xC3, 0x90, 0xC3, 0x91, 0xC3, 0x92, - 0xC3, 0x93, 0xC3, 0x94, 0xC3, 0x95, 0xC3, 0x96, - 0xC3, 0x98, 0xC3, 0x99, 0xC3, 0x9A, 0xC3, 0x9B, - 0xC3, 0x9C, 0xC3, 0x9D, 0xC3, 0x9E, 0xC5, 0xB8, - 0xC4, 0x80, 0xC4, 0x82, 0xC4, 0x84, 0xC4, 0x86, - 0xC4, 0x88, 0xC4, 0x8A, 0xC4, 0x8C, 0xC4, 0x8E, - 0xC4, 0x90, 0xC4, 0x92, 0xC4, 0x94, 0xC4, 0x96, - 0xC4, 0x98, 0xC4, 0x9A, 0xC4, 0x9C, 0xC4, 0x9E, - 0xC4, 0xA0, 0xC4, 0xA2, 0xC4, 0xA4, 0xC4, 0xA6, - 0xC4, 0xA8, 0xC4, 0xAA, 0xC4, 0xAC, 0xC4, 0xAE, - 0x49, 0xC4, 0xB2, 0xC4, 0xB4, 0xC4, 0xB6, 0xC4, - 0xB9, 0xC4, 0xBB, 0xC4, 0xBD, 0xC4, 0xBF, 0xC5, - 0x81, 0xC5, 0x83, 0xC5, 0x85, 0xC5, 0x87, 0xC5, - 0x8A, 0xC5, 0x8C, 0xC5, 0x8E, 0xC5, 0x90, 0xC5, - 0x92, 0xC5, 0x94, 0xC5, 0x96, 0xC5, 0x98, 0xC5, - 0x9A, 0xC5, 0x9C, 0xC5, 0x9E, 0xC5, 0xA0, 0xC5, - 0xA2, 0xC5, 0xA4, 0xC5, 0xA6, 0xC5, 0xA8, 0xC5, - 0xAA, 0xC5, 0xAC, 0xC5, 0xAE, 0xC5, 0xB0, 0xC5, - 0xB2, 0xC5, 0xB4, 0xC5, 0xB6, 0xC5, 0xB9, 0xC5, - 0xBB, 0xC5, 0xBD, 0x53, 0xC6, 0x82, 0xC6, 0x84, - 0xC6, 0x87, 0xC6, 0x8B, 0xC6, 0x91, 0xC7, 0xB6, - 0xC6, 0x98, 0xC8, 0xA0, 0xC6, 0xA0, 0xC6, 0xA2, - 0xC6, 0xA4, 0xC6, 0xA7, 0xC6, 0xAC, 0xC6, 0xAF, - 0xC6, 0xB3, 0xC6, 0xB5, 0xC6, 0xB8, 0xC6, 0xBC, - 0xC7, 0xB7, 0xC7, 0x84, 0xC7, 0x84, 0xC7, 0x87, - 0xC7, 0x87, 0xC7, 0x8A, 0xC7, 0x8A, 0xC7, 0x8D, - 0xC7, 0x8F, 0xC7, 0x91, 0xC7, 0x93, 0xC7, 0x95, - 0xC7, 0x97, 0xC7, 0x99, 0xC7, 0x9B, 0xC6, 0x8E, - 0xC7, 0x9E, 0xC7, 0xA0, 0xC7, 0xA2, 0xC7, 0xA4, - 0xC7, 0xA6, 0xC7, 0xA8, 0xC7, 0xAA, 0xC7, 0xAC, - 0xC7, 0xAE, 0xC7, 0xB1, 0xC7, 0xB1, 0xC7, 0xB4, - 0xC7, 0xB8, 0xC7, 0xBA, 0xC7, 0xBC, 0xC7, 0xBE, - 0xC8, 0x80, 0xC8, 0x82, 0xC8, 0x84, 0xC8, 0x86, - 0xC8, 0x88, 0xC8, 0x8A, 0xC8, 0x8C, 0xC8, 0x8E, - 0xC8, 0x90, 0xC8, 0x92, 0xC8, 0x94, 0xC8, 0x96, - 0xC8, 0x98, 0xC8, 0x9A, 0xC8, 0x9C, 0xC8, 0x9E, - 0xC8, 0xA2, 0xC8, 0xA4, 0xC8, 0xA6, 0xC8, 0xA8, - 0xC8, 0xAA, 0xC8, 0xAC, 0xC8, 0xAE, 0xC8, 0xB0, - 0xC8, 0xB2, 0xC6, 0x81, 0xC6, 0x86, 0xC6, 0x89, - 0xC6, 0x8A, 0xC6, 0x8F, 0xC6, 0x90, 0xC6, 0x93, - 0xC6, 0x94, 0xC6, 0x97, 0xC6, 0x96, 0xC6, 0x9C, - 0xC6, 0x9D, 0xC6, 0x9F, 0xC6, 0xA6, 0xC6, 0xA9, - 0xC6, 0xAE, 0xC6, 0xB1, 0xC6, 0xB2, 0xC6, 0xB7, - 0xCE, 0x99, 0xCE, 0x86, 0xCE, 0x88, 0xCE, 0x89, - 0xCE, 0x8A, 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93, - 0xCE, 0x94, 0xCE, 0x95, 0xCE, 0x96, 0xCE, 0x97, - 0xCE, 0x98, 0xCE, 0x99, 0xCE, 0x9A, 0xCE, 0x9B, - 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, 0xCE, 0x9F, - 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, 0xA3, 0xCE, 0xA3, - 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, 0xCE, 0xA7, - 0xCE, 0xA8, 0xCE, 0xA9, 0xCE, 0xAA, 0xCE, 0xAB, - 0xCE, 0x8C, 0xCE, 0x8E, 0xCE, 0x8F, 0xCE, 0x92, - 0xCE, 0x98, 0xCE, 0xA6, 0xCE, 0xA0, 0xCF, 0x98, - 0xCF, 0x9A, 0xCF, 0x9C, 0xCF, 0x9E, 0xCF, 0xA0, - 0xCF, 0xA2, 0xCF, 0xA4, 0xCF, 0xA6, 0xCF, 0xA8, - 0xCF, 0xAA, 0xCF, 0xAC, 0xCF, 0xAE, 0xCE, 0x9A, - 0xCE, 0xA1, 0xCE, 0xA3, 0xCE, 0x95, 0xD0, 0x90, - 0xD0, 0x91, 0xD0, 0x92, 0xD0, 0x93, 0xD0, 0x94, - 0xD0, 0x95, 0xD0, 0x96, 0xD0, 0x97, 0xD0, 0x98, - 0xD0, 0x99, 0xD0, 0x9A, 0xD0, 0x9B, 0xD0, 0x9C, - 0xD0, 0x9D, 0xD0, 0x9E, 0xD0, 0x9F, 0xD0, 0xA0, - 0xD0, 0xA1, 0xD0, 0xA2, 0xD0, 0xA3, 0xD0, 0xA4, - 0xD0, 0xA5, 0xD0, 0xA6, 0xD0, 0xA7, 0xD0, 0xA8, - 0xD0, 0xA9, 0xD0, 0xAA, 0xD0, 0xAB, 0xD0, 0xAC, - 0xD0, 0xAD, 0xD0, 0xAE, 0xD0, 0xAF, 0xD0, 0x80, - 0xD0, 0x81, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0x84, - 0xD0, 0x85, 0xD0, 0x86, 0xD0, 0x87, 0xD0, 0x88, - 0xD0, 0x89, 0xD0, 0x8A, 0xD0, 0x8B, 0xD0, 0x8C, - 0xD0, 0x8D, 0xD0, 0x8E, 0xD0, 0x8F, 0xD1, 0xA0, - 0xD1, 0xA2, 0xD1, 0xA4, 0xD1, 0xA6, 0xD1, 0xA8, - 0xD1, 0xAA, 0xD1, 0xAC, 0xD1, 0xAE, 0xD1, 0xB0, - 0xD1, 0xB2, 0xD1, 0xB4, 0xD1, 0xB6, 0xD1, 0xB8, - 0xD1, 0xBA, 0xD1, 0xBC, 0xD1, 0xBE, 0xD2, 0x80, - 0xD2, 0x8A, 0xD2, 0x8C, 0xD2, 0x8E, 0xD2, 0x90, - 0xD2, 0x92, 0xD2, 0x94, 0xD2, 0x96, 0xD2, 0x98, - 0xD2, 0x9A, 0xD2, 0x9C, 0xD2, 0x9E, 0xD2, 0xA0, - 0xD2, 0xA2, 0xD2, 0xA4, 0xD2, 0xA6, 0xD2, 0xA8, - 0xD2, 0xAA, 0xD2, 0xAC, 0xD2, 0xAE, 0xD2, 0xB0, - 0xD2, 0xB2, 0xD2, 0xB4, 0xD2, 0xB6, 0xD2, 0xB8, - 0xD2, 0xBA, 0xD2, 0xBC, 0xD2, 0xBE, 0xD3, 0x81, - 0xD3, 0x83, 0xD3, 0x85, 0xD3, 0x87, 0xD3, 0x89, - 0xD3, 0x8B, 0xD3, 0x8D, 0xD3, 0x90, 0xD3, 0x92, - 0xD3, 0x94, 0xD3, 0x96, 0xD3, 0x98, 0xD3, 0x9A, - 0xD3, 0x9C, 0xD3, 0x9E, 0xD3, 0xA0, 0xD3, 0xA2, - 0xD3, 0xA4, 0xD3, 0xA6, 0xD3, 0xA8, 0xD3, 0xAA, - 0xD3, 0xAC, 0xD3, 0xAE, 0xD3, 0xB0, 0xD3, 0xB2, - 0xD3, 0xB4, 0xD3, 0xB8, 0xD4, 0x80, 0xD4, 0x82, - 0xD4, 0x84, 0xD4, 0x86, 0xD4, 0x88, 0xD4, 0x8A, - 0xD4, 0x8C, 0xD4, 0x8E, 0xD4, 0xB1, 0xD4, 0xB2, - 0xD4, 0xB3, 0xD4, 0xB4, 0xD4, 0xB5, 0xD4, 0xB6, - 0xD4, 0xB7, 0xD4, 0xB8, 0xD4, 0xB9, 0xD4, 0xBA, - 0xD4, 0xBB, 0xD4, 0xBC, 0xD4, 0xBD, 0xD4, 0xBE, - 0xD4, 0xBF, 0xD5, 0x80, 0xD5, 0x81, 0xD5, 0x82, - 0xD5, 0x83, 0xD5, 0x84, 0xD5, 0x85, 0xD5, 0x86, - 0xD5, 0x87, 0xD5, 0x88, 0xD5, 0x89, 0xD5, 0x8A, - 0xD5, 0x8B, 0xD5, 0x8C, 0xD5, 0x8D, 0xD5, 0x8E, - 0xD5, 0x8F, 0xD5, 0x90, 0xD5, 0x91, 0xD5, 0x92, - 0xD5, 0x93, 0xD5, 0x94, 0xD5, 0x95, 0xD5, 0x96, - 0xE1, 0xB8, 0x80, 0xE1, 0xB8, 0x82, 0xE1, 0xB8, - 0x84, 0xE1, 0xB8, 0x86, 0xE1, 0xB8, 0x88, 0xE1, - 0xB8, 0x8A, 0xE1, 0xB8, 0x8C, 0xE1, 0xB8, 0x8E, - 0xE1, 0xB8, 0x90, 0xE1, 0xB8, 0x92, 0xE1, 0xB8, - 0x94, 0xE1, 0xB8, 0x96, 0xE1, 0xB8, 0x98, 0xE1, - 0xB8, 0x9A, 0xE1, 0xB8, 0x9C, 0xE1, 0xB8, 0x9E, - 0xE1, 0xB8, 0xA0, 0xE1, 0xB8, 0xA2, 0xE1, 0xB8, - 0xA4, 0xE1, 0xB8, 0xA6, 0xE1, 0xB8, 0xA8, 0xE1, - 0xB8, 0xAA, 0xE1, 0xB8, 0xAC, 0xE1, 0xB8, 0xAE, - 0xE1, 0xB8, 0xB0, 0xE1, 0xB8, 0xB2, 0xE1, 0xB8, - 0xB4, 0xE1, 0xB8, 0xB6, 0xE1, 0xB8, 0xB8, 0xE1, - 0xB8, 0xBA, 0xE1, 0xB8, 0xBC, 0xE1, 0xB8, 0xBE, - 0xE1, 0xB9, 0x80, 0xE1, 0xB9, 0x82, 0xE1, 0xB9, - 0x84, 0xE1, 0xB9, 0x86, 0xE1, 0xB9, 0x88, 0xE1, - 0xB9, 0x8A, 0xE1, 0xB9, 0x8C, 0xE1, 0xB9, 0x8E, - 0xE1, 0xB9, 0x90, 0xE1, 0xB9, 0x92, 0xE1, 0xB9, - 0x94, 0xE1, 0xB9, 0x96, 0xE1, 0xB9, 0x98, 0xE1, - 0xB9, 0x9A, 0xE1, 0xB9, 0x9C, 0xE1, 0xB9, 0x9E, - 0xE1, 0xB9, 0xA0, 0xE1, 0xB9, 0xA2, 0xE1, 0xB9, - 0xA4, 0xE1, 0xB9, 0xA6, 0xE1, 0xB9, 0xA8, 0xE1, - 0xB9, 0xAA, 0xE1, 0xB9, 0xAC, 0xE1, 0xB9, 0xAE, - 0xE1, 0xB9, 0xB0, 0xE1, 0xB9, 0xB2, 0xE1, 0xB9, - 0xB4, 0xE1, 0xB9, 0xB6, 0xE1, 0xB9, 0xB8, 0xE1, - 0xB9, 0xBA, 0xE1, 0xB9, 0xBC, 0xE1, 0xB9, 0xBE, - 0xE1, 0xBA, 0x80, 0xE1, 0xBA, 0x82, 0xE1, 0xBA, - 0x84, 0xE1, 0xBA, 0x86, 0xE1, 0xBA, 0x88, 0xE1, - 0xBA, 0x8A, 0xE1, 0xBA, 0x8C, 0xE1, 0xBA, 0x8E, - 0xE1, 0xBA, 0x90, 0xE1, 0xBA, 0x92, 0xE1, 0xBA, - 0x94, 0xE1, 0xB9, 0xA0, 0xE1, 0xBA, 0xA0, 0xE1, - 0xBA, 0xA2, 0xE1, 0xBA, 0xA4, 0xE1, 0xBA, 0xA6, - 0xE1, 0xBA, 0xA8, 0xE1, 0xBA, 0xAA, 0xE1, 0xBA, - 0xAC, 0xE1, 0xBA, 0xAE, 0xE1, 0xBA, 0xB0, 0xE1, - 0xBA, 0xB2, 0xE1, 0xBA, 0xB4, 0xE1, 0xBA, 0xB6, - 0xE1, 0xBA, 0xB8, 0xE1, 0xBA, 0xBA, 0xE1, 0xBA, - 0xBC, 0xE1, 0xBA, 0xBE, 0xE1, 0xBB, 0x80, 0xE1, - 0xBB, 0x82, 0xE1, 0xBB, 0x84, 0xE1, 0xBB, 0x86, - 0xE1, 0xBB, 0x88, 0xE1, 0xBB, 0x8A, 0xE1, 0xBB, - 0x8C, 0xE1, 0xBB, 0x8E, 0xE1, 0xBB, 0x90, 0xE1, - 0xBB, 0x92, 0xE1, 0xBB, 0x94, 0xE1, 0xBB, 0x96, - 0xE1, 0xBB, 0x98, 0xE1, 0xBB, 0x9A, 0xE1, 0xBB, - 0x9C, 0xE1, 0xBB, 0x9E, 0xE1, 0xBB, 0xA0, 0xE1, - 0xBB, 0xA2, 0xE1, 0xBB, 0xA4, 0xE1, 0xBB, 0xA6, - 0xE1, 0xBB, 0xA8, 0xE1, 0xBB, 0xAA, 0xE1, 0xBB, - 0xAC, 0xE1, 0xBB, 0xAE, 0xE1, 0xBB, 0xB0, 0xE1, - 0xBB, 0xB2, 0xE1, 0xBB, 0xB4, 0xE1, 0xBB, 0xB6, - 0xE1, 0xBB, 0xB8, 0xE1, 0xBC, 0x88, 0xE1, 0xBC, - 0x89, 0xE1, 0xBC, 0x8A, 0xE1, 0xBC, 0x8B, 0xE1, - 0xBC, 0x8C, 0xE1, 0xBC, 0x8D, 0xE1, 0xBC, 0x8E, - 0xE1, 0xBC, 0x8F, 0xE1, 0xBC, 0x98, 0xE1, 0xBC, - 0x99, 0xE1, 0xBC, 0x9A, 0xE1, 0xBC, 0x9B, 0xE1, - 0xBC, 0x9C, 0xE1, 0xBC, 0x9D, 0xE1, 0xBC, 0xA8, - 0xE1, 0xBC, 0xA9, 0xE1, 0xBC, 0xAA, 0xE1, 0xBC, - 0xAB, 0xE1, 0xBC, 0xAC, 0xE1, 0xBC, 0xAD, 0xE1, - 0xBC, 0xAE, 0xE1, 0xBC, 0xAF, 0xE1, 0xBC, 0xB8, - 0xE1, 0xBC, 0xB9, 0xE1, 0xBC, 0xBA, 0xE1, 0xBC, - 0xBB, 0xE1, 0xBC, 0xBC, 0xE1, 0xBC, 0xBD, 0xE1, - 0xBC, 0xBE, 0xE1, 0xBC, 0xBF, 0xE1, 0xBD, 0x88, - 0xE1, 0xBD, 0x89, 0xE1, 0xBD, 0x8A, 0xE1, 0xBD, - 0x8B, 0xE1, 0xBD, 0x8C, 0xE1, 0xBD, 0x8D, 0xE1, - 0xBD, 0x99, 0xE1, 0xBD, 0x9B, 0xE1, 0xBD, 0x9D, - 0xE1, 0xBD, 0x9F, 0xE1, 0xBD, 0xA8, 0xE1, 0xBD, - 0xA9, 0xE1, 0xBD, 0xAA, 0xE1, 0xBD, 0xAB, 0xE1, - 0xBD, 0xAC, 0xE1, 0xBD, 0xAD, 0xE1, 0xBD, 0xAE, - 0xE1, 0xBD, 0xAF, 0xE1, 0xBE, 0xBA, 0xE1, 0xBE, - 0xBB, 0xE1, 0xBF, 0x88, 0xE1, 0xBF, 0x89, 0xE1, - 0xBF, 0x8A, 0xE1, 0xBF, 0x8B, 0xE1, 0xBF, 0x9A, - 0xE1, 0xBF, 0x9B, 0xE1, 0xBF, 0xB8, 0xE1, 0xBF, - 0xB9, 0xE1, 0xBF, 0xAA, 0xE1, 0xBF, 0xAB, 0xE1, - 0xBF, 0xBA, 0xE1, 0xBF, 0xBB, 0xE1, 0xBE, 0x88, - 0xE1, 0xBE, 0x89, 0xE1, 0xBE, 0x8A, 0xE1, 0xBE, - 0x8B, 0xE1, 0xBE, 0x8C, 0xE1, 0xBE, 0x8D, 0xE1, - 0xBE, 0x8E, 0xE1, 0xBE, 0x8F, 0xE1, 0xBE, 0x98, - 0xE1, 0xBE, 0x99, 0xE1, 0xBE, 0x9A, 0xE1, 0xBE, - 0x9B, 0xE1, 0xBE, 0x9C, 0xE1, 0xBE, 0x9D, 0xE1, - 0xBE, 0x9E, 0xE1, 0xBE, 0x9F, 0xE1, 0xBE, 0xA8, - 0xE1, 0xBE, 0xA9, 0xE1, 0xBE, 0xAA, 0xE1, 0xBE, - 0xAB, 0xE1, 0xBE, 0xAC, 0xE1, 0xBE, 0xAD, 0xE1, - 0xBE, 0xAE, 0xE1, 0xBE, 0xAF, 0xE1, 0xBE, 0xB8, - 0xE1, 0xBE, 0xB9, 0xE1, 0xBE, 0xBC, 0xCE, 0x99, - 0xE1, 0xBF, 0x8C, 0xE1, 0xBF, 0x98, 0xE1, 0xBF, - 0x99, 0xE1, 0xBF, 0xA8, 0xE1, 0xBF, 0xA9, 0xE1, - 0xBF, 0xAC, 0xE1, 0xBF, 0xBC, 0xE2, 0x85, 0xA0, - 0xE2, 0x85, 0xA1, 0xE2, 0x85, 0xA2, 0xE2, 0x85, - 0xA3, 0xE2, 0x85, 0xA4, 0xE2, 0x85, 0xA5, 0xE2, - 0x85, 0xA6, 0xE2, 0x85, 0xA7, 0xE2, 0x85, 0xA8, - 0xE2, 0x85, 0xA9, 0xE2, 0x85, 0xAA, 0xE2, 0x85, - 0xAB, 0xE2, 0x85, 0xAC, 0xE2, 0x85, 0xAD, 0xE2, - 0x85, 0xAE, 0xE2, 0x85, 0xAF, 0xE2, 0x92, 0xB6, - 0xE2, 0x92, 0xB7, 0xE2, 0x92, 0xB8, 0xE2, 0x92, - 0xB9, 0xE2, 0x92, 0xBA, 0xE2, 0x92, 0xBB, 0xE2, - 0x92, 0xBC, 0xE2, 0x92, 0xBD, 0xE2, 0x92, 0xBE, - 0xE2, 0x92, 0xBF, 0xE2, 0x93, 0x80, 0xE2, 0x93, - 0x81, 0xE2, 0x93, 0x82, 0xE2, 0x93, 0x83, 0xE2, - 0x93, 0x84, 0xE2, 0x93, 0x85, 0xE2, 0x93, 0x86, - 0xE2, 0x93, 0x87, 0xE2, 0x93, 0x88, 0xE2, 0x93, - 0x89, 0xE2, 0x93, 0x8A, 0xE2, 0x93, 0x8B, 0xE2, - 0x93, 0x8C, 0xE2, 0x93, 0x8D, 0xE2, 0x93, 0x8E, - 0xE2, 0x93, 0x8F, 0xEF, 0xBC, 0xA1, 0xEF, 0xBC, - 0xA2, 0xEF, 0xBC, 0xA3, 0xEF, 0xBC, 0xA4, 0xEF, - 0xBC, 0xA5, 0xEF, 0xBC, 0xA6, 0xEF, 0xBC, 0xA7, - 0xEF, 0xBC, 0xA8, 0xEF, 0xBC, 0xA9, 0xEF, 0xBC, - 0xAA, 0xEF, 0xBC, 0xAB, 0xEF, 0xBC, 0xAC, 0xEF, - 0xBC, 0xAD, 0xEF, 0xBC, 0xAE, 0xEF, 0xBC, 0xAF, - 0xEF, 0xBC, 0xB0, 0xEF, 0xBC, 0xB1, 0xEF, 0xBC, - 0xB2, 0xEF, 0xBC, 0xB3, 0xEF, 0xBC, 0xB4, 0xEF, - 0xBC, 0xB5, 0xEF, 0xBC, 0xB6, 0xEF, 0xBC, 0xB7, - 0xEF, 0xBC, 0xB8, 0xEF, 0xBC, 0xB9, 0xEF, 0xBC, - 0xBA, 0xF0, 0x90, 0x90, 0x80, 0xF0, 0x90, 0x90, - 0x81, 0xF0, 0x90, 0x90, 0x82, 0xF0, 0x90, 0x90, - 0x83, 0xF0, 0x90, 0x90, 0x84, 0xF0, 0x90, 0x90, - 0x85, 0xF0, 0x90, 0x90, 0x86, 0xF0, 0x90, 0x90, - 0x87, 0xF0, 0x90, 0x90, 0x88, 0xF0, 0x90, 0x90, - 0x89, 0xF0, 0x90, 0x90, 0x8A, 0xF0, 0x90, 0x90, - 0x8B, 0xF0, 0x90, 0x90, 0x8C, 0xF0, 0x90, 0x90, - 0x8D, 0xF0, 0x90, 0x90, 0x8E, 0xF0, 0x90, 0x90, - 0x8F, 0xF0, 0x90, 0x90, 0x90, 0xF0, 0x90, 0x90, - 0x91, 0xF0, 0x90, 0x90, 0x92, 0xF0, 0x90, 0x90, - 0x93, 0xF0, 0x90, 0x90, 0x94, 0xF0, 0x90, 0x90, - 0x95, 0xF0, 0x90, 0x90, 0x96, 0xF0, 0x90, 0x90, - 0x97, 0xF0, 0x90, 0x90, 0x98, 0xF0, 0x90, 0x90, - 0x99, 0xF0, 0x90, 0x90, 0x9A, 0xF0, 0x90, 0x90, - 0x9B, 0xF0, 0x90, 0x90, 0x9C, 0xF0, 0x90, 0x90, - 0x9D, 0xF0, 0x90, 0x90, 0x9E, 0xF0, 0x90, 0x90, - 0x9F, 0xF0, 0x90, 0x90, 0xA0, 0xF0, 0x90, 0x90, - 0xA1, 0xF0, 0x90, 0x90, 0xA2, 0xF0, 0x90, 0x90, - 0xA3, 0xF0, 0x90, 0x90, 0xA4, 0xF0, 0x90, 0x90, - 0xA5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - }, - { - 0xCE, 0x9C, 0xC3, 0x80, 0xC3, 0x81, 0xC3, 0x82, - 0xC3, 0x83, 0xC3, 0x84, 0xC3, 0x85, 0xC3, 0x86, - 0xC3, 0x87, 0xC3, 0x88, 0xC3, 0x89, 0xC3, 0x8A, - 0xC3, 0x8B, 0xC3, 0x8C, 0xC3, 0x8D, 0xC3, 0x8E, - 0xC3, 0x8F, 0xC3, 0x90, 0xC3, 0x91, 0xC3, 0x92, - 0xC3, 0x93, 0xC3, 0x94, 0xC3, 0x95, 0xC3, 0x96, - 0xC3, 0x98, 0xC3, 0x99, 0xC3, 0x9A, 0xC3, 0x9B, - 0xC3, 0x9C, 0xC3, 0x9D, 0xC3, 0x9E, 0xC5, 0xB8, - 0xC4, 0x80, 0xC4, 0x82, 0xC4, 0x84, 0xC4, 0x86, - 0xC4, 0x88, 0xC4, 0x8A, 0xC4, 0x8C, 0xC4, 0x8E, - 0xC4, 0x90, 0xC4, 0x92, 0xC4, 0x94, 0xC4, 0x96, - 0xC4, 0x98, 0xC4, 0x9A, 0xC4, 0x9C, 0xC4, 0x9E, - 0xC4, 0xA0, 0xC4, 0xA2, 0xC4, 0xA4, 0xC4, 0xA6, - 0xC4, 0xA8, 0xC4, 0xAA, 0xC4, 0xAC, 0xC4, 0xAE, - 0x49, 0xC4, 0xB2, 0xC4, 0xB4, 0xC4, 0xB6, 0xC4, - 0xB9, 0xC4, 0xBB, 0xC4, 0xBD, 0xC4, 0xBF, 0xC5, - 0x81, 0xC5, 0x83, 0xC5, 0x85, 0xC5, 0x87, 0xC5, - 0x8A, 0xC5, 0x8C, 0xC5, 0x8E, 0xC5, 0x90, 0xC5, - 0x92, 0xC5, 0x94, 0xC5, 0x96, 0xC5, 0x98, 0xC5, - 0x9A, 0xC5, 0x9C, 0xC5, 0x9E, 0xC5, 0xA0, 0xC5, - 0xA2, 0xC5, 0xA4, 0xC5, 0xA6, 0xC5, 0xA8, 0xC5, - 0xAA, 0xC5, 0xAC, 0xC5, 0xAE, 0xC5, 0xB0, 0xC5, - 0xB2, 0xC5, 0xB4, 0xC5, 0xB6, 0xC5, 0xB9, 0xC5, - 0xBB, 0xC5, 0xBD, 0x53, 0xC9, 0x83, 0xC6, 0x82, - 0xC6, 0x84, 0xC6, 0x87, 0xC6, 0x8B, 0xC6, 0x91, - 0xC7, 0xB6, 0xC6, 0x98, 0xC8, 0xBD, 0xC8, 0xA0, - 0xC6, 0xA0, 0xC6, 0xA2, 0xC6, 0xA4, 0xC6, 0xA7, - 0xC6, 0xAC, 0xC6, 0xAF, 0xC6, 0xB3, 0xC6, 0xB5, - 0xC6, 0xB8, 0xC6, 0xBC, 0xC7, 0xB7, 0xC7, 0x84, - 0xC7, 0x84, 0xC7, 0x87, 0xC7, 0x87, 0xC7, 0x8A, - 0xC7, 0x8A, 0xC7, 0x8D, 0xC7, 0x8F, 0xC7, 0x91, - 0xC7, 0x93, 0xC7, 0x95, 0xC7, 0x97, 0xC7, 0x99, - 0xC7, 0x9B, 0xC6, 0x8E, 0xC7, 0x9E, 0xC7, 0xA0, - 0xC7, 0xA2, 0xC7, 0xA4, 0xC7, 0xA6, 0xC7, 0xA8, - 0xC7, 0xAA, 0xC7, 0xAC, 0xC7, 0xAE, 0xC7, 0xB1, - 0xC7, 0xB1, 0xC7, 0xB4, 0xC7, 0xB8, 0xC7, 0xBA, - 0xC7, 0xBC, 0xC7, 0xBE, 0xC8, 0x80, 0xC8, 0x82, - 0xC8, 0x84, 0xC8, 0x86, 0xC8, 0x88, 0xC8, 0x8A, - 0xC8, 0x8C, 0xC8, 0x8E, 0xC8, 0x90, 0xC8, 0x92, - 0xC8, 0x94, 0xC8, 0x96, 0xC8, 0x98, 0xC8, 0x9A, - 0xC8, 0x9C, 0xC8, 0x9E, 0xC8, 0xA2, 0xC8, 0xA4, - 0xC8, 0xA6, 0xC8, 0xA8, 0xC8, 0xAA, 0xC8, 0xAC, - 0xC8, 0xAE, 0xC8, 0xB0, 0xC8, 0xB2, 0xC8, 0xBB, - 0xC9, 0x81, 0xC9, 0x86, 0xC9, 0x88, 0xC9, 0x8A, - 0xC9, 0x8C, 0xC9, 0x8E, 0xC6, 0x81, 0xC6, 0x86, - 0xC6, 0x89, 0xC6, 0x8A, 0xC6, 0x8F, 0xC6, 0x90, - 0xC6, 0x93, 0xC6, 0x94, 0xC6, 0x97, 0xC6, 0x96, - 0xE2, 0xB1, 0xA2, 0xC6, 0x9C, 0xC6, 0x9D, 0xC6, - 0x9F, 0xE2, 0xB1, 0xA4, 0xC6, 0xA6, 0xC6, 0xA9, - 0xC6, 0xAE, 0xC9, 0x84, 0xC6, 0xB1, 0xC6, 0xB2, - 0xC9, 0x85, 0xC6, 0xB7, 0xCE, 0x99, 0xCF, 0xBD, - 0xCF, 0xBE, 0xCF, 0xBF, 0xCE, 0x86, 0xCE, 0x88, - 0xCE, 0x89, 0xCE, 0x8A, 0xCE, 0x91, 0xCE, 0x92, - 0xCE, 0x93, 0xCE, 0x94, 0xCE, 0x95, 0xCE, 0x96, - 0xCE, 0x97, 0xCE, 0x98, 0xCE, 0x99, 0xCE, 0x9A, - 0xCE, 0x9B, 0xCE, 0x9C, 0xCE, 0x9D, 0xCE, 0x9E, - 0xCE, 0x9F, 0xCE, 0xA0, 0xCE, 0xA1, 0xCE, 0xA3, - 0xCE, 0xA3, 0xCE, 0xA4, 0xCE, 0xA5, 0xCE, 0xA6, - 0xCE, 0xA7, 0xCE, 0xA8, 0xCE, 0xA9, 0xCE, 0xAA, - 0xCE, 0xAB, 0xCE, 0x8C, 0xCE, 0x8E, 0xCE, 0x8F, - 0xCE, 0x92, 0xCE, 0x98, 0xCE, 0xA6, 0xCE, 0xA0, - 0xCF, 0x98, 0xCF, 0x9A, 0xCF, 0x9C, 0xCF, 0x9E, - 0xCF, 0xA0, 0xCF, 0xA2, 0xCF, 0xA4, 0xCF, 0xA6, - 0xCF, 0xA8, 0xCF, 0xAA, 0xCF, 0xAC, 0xCF, 0xAE, - 0xCE, 0x9A, 0xCE, 0xA1, 0xCF, 0xB9, 0xCE, 0x95, - 0xCF, 0xB7, 0xCF, 0xBA, 0xD0, 0x90, 0xD0, 0x91, - 0xD0, 0x92, 0xD0, 0x93, 0xD0, 0x94, 0xD0, 0x95, - 0xD0, 0x96, 0xD0, 0x97, 0xD0, 0x98, 0xD0, 0x99, - 0xD0, 0x9A, 0xD0, 0x9B, 0xD0, 0x9C, 0xD0, 0x9D, - 0xD0, 0x9E, 0xD0, 0x9F, 0xD0, 0xA0, 0xD0, 0xA1, - 0xD0, 0xA2, 0xD0, 0xA3, 0xD0, 0xA4, 0xD0, 0xA5, - 0xD0, 0xA6, 0xD0, 0xA7, 0xD0, 0xA8, 0xD0, 0xA9, - 0xD0, 0xAA, 0xD0, 0xAB, 0xD0, 0xAC, 0xD0, 0xAD, - 0xD0, 0xAE, 0xD0, 0xAF, 0xD0, 0x80, 0xD0, 0x81, - 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0x84, 0xD0, 0x85, - 0xD0, 0x86, 0xD0, 0x87, 0xD0, 0x88, 0xD0, 0x89, - 0xD0, 0x8A, 0xD0, 0x8B, 0xD0, 0x8C, 0xD0, 0x8D, - 0xD0, 0x8E, 0xD0, 0x8F, 0xD1, 0xA0, 0xD1, 0xA2, - 0xD1, 0xA4, 0xD1, 0xA6, 0xD1, 0xA8, 0xD1, 0xAA, - 0xD1, 0xAC, 0xD1, 0xAE, 0xD1, 0xB0, 0xD1, 0xB2, - 0xD1, 0xB4, 0xD1, 0xB6, 0xD1, 0xB8, 0xD1, 0xBA, - 0xD1, 0xBC, 0xD1, 0xBE, 0xD2, 0x80, 0xD2, 0x8A, - 0xD2, 0x8C, 0xD2, 0x8E, 0xD2, 0x90, 0xD2, 0x92, - 0xD2, 0x94, 0xD2, 0x96, 0xD2, 0x98, 0xD2, 0x9A, - 0xD2, 0x9C, 0xD2, 0x9E, 0xD2, 0xA0, 0xD2, 0xA2, - 0xD2, 0xA4, 0xD2, 0xA6, 0xD2, 0xA8, 0xD2, 0xAA, - 0xD2, 0xAC, 0xD2, 0xAE, 0xD2, 0xB0, 0xD2, 0xB2, - 0xD2, 0xB4, 0xD2, 0xB6, 0xD2, 0xB8, 0xD2, 0xBA, - 0xD2, 0xBC, 0xD2, 0xBE, 0xD3, 0x81, 0xD3, 0x83, - 0xD3, 0x85, 0xD3, 0x87, 0xD3, 0x89, 0xD3, 0x8B, - 0xD3, 0x8D, 0xD3, 0x80, 0xD3, 0x90, 0xD3, 0x92, - 0xD3, 0x94, 0xD3, 0x96, 0xD3, 0x98, 0xD3, 0x9A, - 0xD3, 0x9C, 0xD3, 0x9E, 0xD3, 0xA0, 0xD3, 0xA2, - 0xD3, 0xA4, 0xD3, 0xA6, 0xD3, 0xA8, 0xD3, 0xAA, - 0xD3, 0xAC, 0xD3, 0xAE, 0xD3, 0xB0, 0xD3, 0xB2, - 0xD3, 0xB4, 0xD3, 0xB6, 0xD3, 0xB8, 0xD3, 0xBA, - 0xD3, 0xBC, 0xD3, 0xBE, 0xD4, 0x80, 0xD4, 0x82, - 0xD4, 0x84, 0xD4, 0x86, 0xD4, 0x88, 0xD4, 0x8A, - 0xD4, 0x8C, 0xD4, 0x8E, 0xD4, 0x90, 0xD4, 0x92, - 0xD4, 0xB1, 0xD4, 0xB2, 0xD4, 0xB3, 0xD4, 0xB4, - 0xD4, 0xB5, 0xD4, 0xB6, 0xD4, 0xB7, 0xD4, 0xB8, - 0xD4, 0xB9, 0xD4, 0xBA, 0xD4, 0xBB, 0xD4, 0xBC, - 0xD4, 0xBD, 0xD4, 0xBE, 0xD4, 0xBF, 0xD5, 0x80, - 0xD5, 0x81, 0xD5, 0x82, 0xD5, 0x83, 0xD5, 0x84, - 0xD5, 0x85, 0xD5, 0x86, 0xD5, 0x87, 0xD5, 0x88, - 0xD5, 0x89, 0xD5, 0x8A, 0xD5, 0x8B, 0xD5, 0x8C, - 0xD5, 0x8D, 0xD5, 0x8E, 0xD5, 0x8F, 0xD5, 0x90, - 0xD5, 0x91, 0xD5, 0x92, 0xD5, 0x93, 0xD5, 0x94, - 0xD5, 0x95, 0xD5, 0x96, 0xE2, 0xB1, 0xA3, 0xE1, - 0xB8, 0x80, 0xE1, 0xB8, 0x82, 0xE1, 0xB8, 0x84, - 0xE1, 0xB8, 0x86, 0xE1, 0xB8, 0x88, 0xE1, 0xB8, - 0x8A, 0xE1, 0xB8, 0x8C, 0xE1, 0xB8, 0x8E, 0xE1, - 0xB8, 0x90, 0xE1, 0xB8, 0x92, 0xE1, 0xB8, 0x94, - 0xE1, 0xB8, 0x96, 0xE1, 0xB8, 0x98, 0xE1, 0xB8, - 0x9A, 0xE1, 0xB8, 0x9C, 0xE1, 0xB8, 0x9E, 0xE1, - 0xB8, 0xA0, 0xE1, 0xB8, 0xA2, 0xE1, 0xB8, 0xA4, - 0xE1, 0xB8, 0xA6, 0xE1, 0xB8, 0xA8, 0xE1, 0xB8, - 0xAA, 0xE1, 0xB8, 0xAC, 0xE1, 0xB8, 0xAE, 0xE1, - 0xB8, 0xB0, 0xE1, 0xB8, 0xB2, 0xE1, 0xB8, 0xB4, - 0xE1, 0xB8, 0xB6, 0xE1, 0xB8, 0xB8, 0xE1, 0xB8, - 0xBA, 0xE1, 0xB8, 0xBC, 0xE1, 0xB8, 0xBE, 0xE1, - 0xB9, 0x80, 0xE1, 0xB9, 0x82, 0xE1, 0xB9, 0x84, - 0xE1, 0xB9, 0x86, 0xE1, 0xB9, 0x88, 0xE1, 0xB9, - 0x8A, 0xE1, 0xB9, 0x8C, 0xE1, 0xB9, 0x8E, 0xE1, - 0xB9, 0x90, 0xE1, 0xB9, 0x92, 0xE1, 0xB9, 0x94, - 0xE1, 0xB9, 0x96, 0xE1, 0xB9, 0x98, 0xE1, 0xB9, - 0x9A, 0xE1, 0xB9, 0x9C, 0xE1, 0xB9, 0x9E, 0xE1, - 0xB9, 0xA0, 0xE1, 0xB9, 0xA2, 0xE1, 0xB9, 0xA4, - 0xE1, 0xB9, 0xA6, 0xE1, 0xB9, 0xA8, 0xE1, 0xB9, - 0xAA, 0xE1, 0xB9, 0xAC, 0xE1, 0xB9, 0xAE, 0xE1, - 0xB9, 0xB0, 0xE1, 0xB9, 0xB2, 0xE1, 0xB9, 0xB4, - 0xE1, 0xB9, 0xB6, 0xE1, 0xB9, 0xB8, 0xE1, 0xB9, - 0xBA, 0xE1, 0xB9, 0xBC, 0xE1, 0xB9, 0xBE, 0xE1, - 0xBA, 0x80, 0xE1, 0xBA, 0x82, 0xE1, 0xBA, 0x84, - 0xE1, 0xBA, 0x86, 0xE1, 0xBA, 0x88, 0xE1, 0xBA, - 0x8A, 0xE1, 0xBA, 0x8C, 0xE1, 0xBA, 0x8E, 0xE1, - 0xBA, 0x90, 0xE1, 0xBA, 0x92, 0xE1, 0xBA, 0x94, - 0xE1, 0xB9, 0xA0, 0xE1, 0xBA, 0xA0, 0xE1, 0xBA, - 0xA2, 0xE1, 0xBA, 0xA4, 0xE1, 0xBA, 0xA6, 0xE1, - 0xBA, 0xA8, 0xE1, 0xBA, 0xAA, 0xE1, 0xBA, 0xAC, - 0xE1, 0xBA, 0xAE, 0xE1, 0xBA, 0xB0, 0xE1, 0xBA, - 0xB2, 0xE1, 0xBA, 0xB4, 0xE1, 0xBA, 0xB6, 0xE1, - 0xBA, 0xB8, 0xE1, 0xBA, 0xBA, 0xE1, 0xBA, 0xBC, - 0xE1, 0xBA, 0xBE, 0xE1, 0xBB, 0x80, 0xE1, 0xBB, - 0x82, 0xE1, 0xBB, 0x84, 0xE1, 0xBB, 0x86, 0xE1, - 0xBB, 0x88, 0xE1, 0xBB, 0x8A, 0xE1, 0xBB, 0x8C, - 0xE1, 0xBB, 0x8E, 0xE1, 0xBB, 0x90, 0xE1, 0xBB, - 0x92, 0xE1, 0xBB, 0x94, 0xE1, 0xBB, 0x96, 0xE1, - 0xBB, 0x98, 0xE1, 0xBB, 0x9A, 0xE1, 0xBB, 0x9C, - 0xE1, 0xBB, 0x9E, 0xE1, 0xBB, 0xA0, 0xE1, 0xBB, - 0xA2, 0xE1, 0xBB, 0xA4, 0xE1, 0xBB, 0xA6, 0xE1, - 0xBB, 0xA8, 0xE1, 0xBB, 0xAA, 0xE1, 0xBB, 0xAC, - 0xE1, 0xBB, 0xAE, 0xE1, 0xBB, 0xB0, 0xE1, 0xBB, - 0xB2, 0xE1, 0xBB, 0xB4, 0xE1, 0xBB, 0xB6, 0xE1, - 0xBB, 0xB8, 0xE1, 0xBC, 0x88, 0xE1, 0xBC, 0x89, - 0xE1, 0xBC, 0x8A, 0xE1, 0xBC, 0x8B, 0xE1, 0xBC, - 0x8C, 0xE1, 0xBC, 0x8D, 0xE1, 0xBC, 0x8E, 0xE1, - 0xBC, 0x8F, 0xE1, 0xBC, 0x98, 0xE1, 0xBC, 0x99, - 0xE1, 0xBC, 0x9A, 0xE1, 0xBC, 0x9B, 0xE1, 0xBC, - 0x9C, 0xE1, 0xBC, 0x9D, 0xE1, 0xBC, 0xA8, 0xE1, - 0xBC, 0xA9, 0xE1, 0xBC, 0xAA, 0xE1, 0xBC, 0xAB, - 0xE1, 0xBC, 0xAC, 0xE1, 0xBC, 0xAD, 0xE1, 0xBC, - 0xAE, 0xE1, 0xBC, 0xAF, 0xE1, 0xBC, 0xB8, 0xE1, - 0xBC, 0xB9, 0xE1, 0xBC, 0xBA, 0xE1, 0xBC, 0xBB, - 0xE1, 0xBC, 0xBC, 0xE1, 0xBC, 0xBD, 0xE1, 0xBC, - 0xBE, 0xE1, 0xBC, 0xBF, 0xE1, 0xBD, 0x88, 0xE1, - 0xBD, 0x89, 0xE1, 0xBD, 0x8A, 0xE1, 0xBD, 0x8B, - 0xE1, 0xBD, 0x8C, 0xE1, 0xBD, 0x8D, 0xE1, 0xBD, - 0x99, 0xE1, 0xBD, 0x9B, 0xE1, 0xBD, 0x9D, 0xE1, - 0xBD, 0x9F, 0xE1, 0xBD, 0xA8, 0xE1, 0xBD, 0xA9, - 0xE1, 0xBD, 0xAA, 0xE1, 0xBD, 0xAB, 0xE1, 0xBD, - 0xAC, 0xE1, 0xBD, 0xAD, 0xE1, 0xBD, 0xAE, 0xE1, - 0xBD, 0xAF, 0xE1, 0xBE, 0xBA, 0xE1, 0xBE, 0xBB, - 0xE1, 0xBF, 0x88, 0xE1, 0xBF, 0x89, 0xE1, 0xBF, - 0x8A, 0xE1, 0xBF, 0x8B, 0xE1, 0xBF, 0x9A, 0xE1, - 0xBF, 0x9B, 0xE1, 0xBF, 0xB8, 0xE1, 0xBF, 0xB9, - 0xE1, 0xBF, 0xAA, 0xE1, 0xBF, 0xAB, 0xE1, 0xBF, - 0xBA, 0xE1, 0xBF, 0xBB, 0xE1, 0xBE, 0x88, 0xE1, - 0xBE, 0x89, 0xE1, 0xBE, 0x8A, 0xE1, 0xBE, 0x8B, - 0xE1, 0xBE, 0x8C, 0xE1, 0xBE, 0x8D, 0xE1, 0xBE, - 0x8E, 0xE1, 0xBE, 0x8F, 0xE1, 0xBE, 0x98, 0xE1, - 0xBE, 0x99, 0xE1, 0xBE, 0x9A, 0xE1, 0xBE, 0x9B, - 0xE1, 0xBE, 0x9C, 0xE1, 0xBE, 0x9D, 0xE1, 0xBE, - 0x9E, 0xE1, 0xBE, 0x9F, 0xE1, 0xBE, 0xA8, 0xE1, - 0xBE, 0xA9, 0xE1, 0xBE, 0xAA, 0xE1, 0xBE, 0xAB, - 0xE1, 0xBE, 0xAC, 0xE1, 0xBE, 0xAD, 0xE1, 0xBE, - 0xAE, 0xE1, 0xBE, 0xAF, 0xE1, 0xBE, 0xB8, 0xE1, - 0xBE, 0xB9, 0xE1, 0xBE, 0xBC, 0xCE, 0x99, 0xE1, - 0xBF, 0x8C, 0xE1, 0xBF, 0x98, 0xE1, 0xBF, 0x99, - 0xE1, 0xBF, 0xA8, 0xE1, 0xBF, 0xA9, 0xE1, 0xBF, - 0xAC, 0xE1, 0xBF, 0xBC, 0xE2, 0x84, 0xB2, 0xE2, - 0x85, 0xA0, 0xE2, 0x85, 0xA1, 0xE2, 0x85, 0xA2, - 0xE2, 0x85, 0xA3, 0xE2, 0x85, 0xA4, 0xE2, 0x85, - 0xA5, 0xE2, 0x85, 0xA6, 0xE2, 0x85, 0xA7, 0xE2, - 0x85, 0xA8, 0xE2, 0x85, 0xA9, 0xE2, 0x85, 0xAA, - 0xE2, 0x85, 0xAB, 0xE2, 0x85, 0xAC, 0xE2, 0x85, - 0xAD, 0xE2, 0x85, 0xAE, 0xE2, 0x85, 0xAF, 0xE2, - 0x86, 0x83, 0xE2, 0x92, 0xB6, 0xE2, 0x92, 0xB7, - 0xE2, 0x92, 0xB8, 0xE2, 0x92, 0xB9, 0xE2, 0x92, - 0xBA, 0xE2, 0x92, 0xBB, 0xE2, 0x92, 0xBC, 0xE2, - 0x92, 0xBD, 0xE2, 0x92, 0xBE, 0xE2, 0x92, 0xBF, - 0xE2, 0x93, 0x80, 0xE2, 0x93, 0x81, 0xE2, 0x93, - 0x82, 0xE2, 0x93, 0x83, 0xE2, 0x93, 0x84, 0xE2, - 0x93, 0x85, 0xE2, 0x93, 0x86, 0xE2, 0x93, 0x87, - 0xE2, 0x93, 0x88, 0xE2, 0x93, 0x89, 0xE2, 0x93, - 0x8A, 0xE2, 0x93, 0x8B, 0xE2, 0x93, 0x8C, 0xE2, - 0x93, 0x8D, 0xE2, 0x93, 0x8E, 0xE2, 0x93, 0x8F, - 0xE2, 0xB0, 0x80, 0xE2, 0xB0, 0x81, 0xE2, 0xB0, - 0x82, 0xE2, 0xB0, 0x83, 0xE2, 0xB0, 0x84, 0xE2, - 0xB0, 0x85, 0xE2, 0xB0, 0x86, 0xE2, 0xB0, 0x87, - 0xE2, 0xB0, 0x88, 0xE2, 0xB0, 0x89, 0xE2, 0xB0, - 0x8A, 0xE2, 0xB0, 0x8B, 0xE2, 0xB0, 0x8C, 0xE2, - 0xB0, 0x8D, 0xE2, 0xB0, 0x8E, 0xE2, 0xB0, 0x8F, - 0xE2, 0xB0, 0x90, 0xE2, 0xB0, 0x91, 0xE2, 0xB0, - 0x92, 0xE2, 0xB0, 0x93, 0xE2, 0xB0, 0x94, 0xE2, - 0xB0, 0x95, 0xE2, 0xB0, 0x96, 0xE2, 0xB0, 0x97, - 0xE2, 0xB0, 0x98, 0xE2, 0xB0, 0x99, 0xE2, 0xB0, - 0x9A, 0xE2, 0xB0, 0x9B, 0xE2, 0xB0, 0x9C, 0xE2, - 0xB0, 0x9D, 0xE2, 0xB0, 0x9E, 0xE2, 0xB0, 0x9F, - 0xE2, 0xB0, 0xA0, 0xE2, 0xB0, 0xA1, 0xE2, 0xB0, - 0xA2, 0xE2, 0xB0, 0xA3, 0xE2, 0xB0, 0xA4, 0xE2, - 0xB0, 0xA5, 0xE2, 0xB0, 0xA6, 0xE2, 0xB0, 0xA7, - 0xE2, 0xB0, 0xA8, 0xE2, 0xB0, 0xA9, 0xE2, 0xB0, - 0xAA, 0xE2, 0xB0, 0xAB, 0xE2, 0xB0, 0xAC, 0xE2, - 0xB0, 0xAD, 0xE2, 0xB0, 0xAE, 0xE2, 0xB1, 0xA0, - 0xC8, 0xBA, 0xC8, 0xBE, 0xE2, 0xB1, 0xA7, 0xE2, - 0xB1, 0xA9, 0xE2, 0xB1, 0xAB, 0xE2, 0xB1, 0xB5, - 0xE2, 0xB2, 0x80, 0xE2, 0xB2, 0x82, 0xE2, 0xB2, - 0x84, 0xE2, 0xB2, 0x86, 0xE2, 0xB2, 0x88, 0xE2, - 0xB2, 0x8A, 0xE2, 0xB2, 0x8C, 0xE2, 0xB2, 0x8E, - 0xE2, 0xB2, 0x90, 0xE2, 0xB2, 0x92, 0xE2, 0xB2, - 0x94, 0xE2, 0xB2, 0x96, 0xE2, 0xB2, 0x98, 0xE2, - 0xB2, 0x9A, 0xE2, 0xB2, 0x9C, 0xE2, 0xB2, 0x9E, - 0xE2, 0xB2, 0xA0, 0xE2, 0xB2, 0xA2, 0xE2, 0xB2, - 0xA4, 0xE2, 0xB2, 0xA6, 0xE2, 0xB2, 0xA8, 0xE2, - 0xB2, 0xAA, 0xE2, 0xB2, 0xAC, 0xE2, 0xB2, 0xAE, - 0xE2, 0xB2, 0xB0, 0xE2, 0xB2, 0xB2, 0xE2, 0xB2, - 0xB4, 0xE2, 0xB2, 0xB6, 0xE2, 0xB2, 0xB8, 0xE2, - 0xB2, 0xBA, 0xE2, 0xB2, 0xBC, 0xE2, 0xB2, 0xBE, - 0xE2, 0xB3, 0x80, 0xE2, 0xB3, 0x82, 0xE2, 0xB3, - 0x84, 0xE2, 0xB3, 0x86, 0xE2, 0xB3, 0x88, 0xE2, - 0xB3, 0x8A, 0xE2, 0xB3, 0x8C, 0xE2, 0xB3, 0x8E, - 0xE2, 0xB3, 0x90, 0xE2, 0xB3, 0x92, 0xE2, 0xB3, - 0x94, 0xE2, 0xB3, 0x96, 0xE2, 0xB3, 0x98, 0xE2, - 0xB3, 0x9A, 0xE2, 0xB3, 0x9C, 0xE2, 0xB3, 0x9E, - 0xE2, 0xB3, 0xA0, 0xE2, 0xB3, 0xA2, 0xE1, 0x82, - 0xA0, 0xE1, 0x82, 0xA1, 0xE1, 0x82, 0xA2, 0xE1, - 0x82, 0xA3, 0xE1, 0x82, 0xA4, 0xE1, 0x82, 0xA5, - 0xE1, 0x82, 0xA6, 0xE1, 0x82, 0xA7, 0xE1, 0x82, - 0xA8, 0xE1, 0x82, 0xA9, 0xE1, 0x82, 0xAA, 0xE1, - 0x82, 0xAB, 0xE1, 0x82, 0xAC, 0xE1, 0x82, 0xAD, - 0xE1, 0x82, 0xAE, 0xE1, 0x82, 0xAF, 0xE1, 0x82, - 0xB0, 0xE1, 0x82, 0xB1, 0xE1, 0x82, 0xB2, 0xE1, - 0x82, 0xB3, 0xE1, 0x82, 0xB4, 0xE1, 0x82, 0xB5, - 0xE1, 0x82, 0xB6, 0xE1, 0x82, 0xB7, 0xE1, 0x82, - 0xB8, 0xE1, 0x82, 0xB9, 0xE1, 0x82, 0xBA, 0xE1, - 0x82, 0xBB, 0xE1, 0x82, 0xBC, 0xE1, 0x82, 0xBD, - 0xE1, 0x82, 0xBE, 0xE1, 0x82, 0xBF, 0xE1, 0x83, - 0x80, 0xE1, 0x83, 0x81, 0xE1, 0x83, 0x82, 0xE1, - 0x83, 0x83, 0xE1, 0x83, 0x84, 0xE1, 0x83, 0x85, - 0xEF, 0xBC, 0xA1, 0xEF, 0xBC, 0xA2, 0xEF, 0xBC, - 0xA3, 0xEF, 0xBC, 0xA4, 0xEF, 0xBC, 0xA5, 0xEF, - 0xBC, 0xA6, 0xEF, 0xBC, 0xA7, 0xEF, 0xBC, 0xA8, - 0xEF, 0xBC, 0xA9, 0xEF, 0xBC, 0xAA, 0xEF, 0xBC, - 0xAB, 0xEF, 0xBC, 0xAC, 0xEF, 0xBC, 0xAD, 0xEF, - 0xBC, 0xAE, 0xEF, 0xBC, 0xAF, 0xEF, 0xBC, 0xB0, - 0xEF, 0xBC, 0xB1, 0xEF, 0xBC, 0xB2, 0xEF, 0xBC, - 0xB3, 0xEF, 0xBC, 0xB4, 0xEF, 0xBC, 0xB5, 0xEF, - 0xBC, 0xB6, 0xEF, 0xBC, 0xB7, 0xEF, 0xBC, 0xB8, - 0xEF, 0xBC, 0xB9, 0xEF, 0xBC, 0xBA, 0xF0, 0x90, - 0x90, 0x80, 0xF0, 0x90, 0x90, 0x81, 0xF0, 0x90, - 0x90, 0x82, 0xF0, 0x90, 0x90, 0x83, 0xF0, 0x90, - 0x90, 0x84, 0xF0, 0x90, 0x90, 0x85, 0xF0, 0x90, - 0x90, 0x86, 0xF0, 0x90, 0x90, 0x87, 0xF0, 0x90, - 0x90, 0x88, 0xF0, 0x90, 0x90, 0x89, 0xF0, 0x90, - 0x90, 0x8A, 0xF0, 0x90, 0x90, 0x8B, 0xF0, 0x90, - 0x90, 0x8C, 0xF0, 0x90, 0x90, 0x8D, 0xF0, 0x90, - 0x90, 0x8E, 0xF0, 0x90, 0x90, 0x8F, 0xF0, 0x90, - 0x90, 0x90, 0xF0, 0x90, 0x90, 0x91, 0xF0, 0x90, - 0x90, 0x92, 0xF0, 0x90, 0x90, 0x93, 0xF0, 0x90, - 0x90, 0x94, 0xF0, 0x90, 0x90, 0x95, 0xF0, 0x90, - 0x90, 0x96, 0xF0, 0x90, 0x90, 0x97, 0xF0, 0x90, - 0x90, 0x98, 0xF0, 0x90, 0x90, 0x99, 0xF0, 0x90, - 0x90, 0x9A, 0xF0, 0x90, 0x90, 0x9B, 0xF0, 0x90, - 0x90, 0x9C, 0xF0, 0x90, 0x90, 0x9D, 0xF0, 0x90, - 0x90, 0x9E, 0xF0, 0x90, 0x90, 0x9F, 0xF0, 0x90, - 0x90, 0xA0, 0xF0, 0x90, 0x90, 0xA1, 0xF0, 0x90, - 0x90, 0xA2, 0xF0, 0x90, 0x90, 0xA3, 0xF0, 0x90, - 0x90, 0xA4, 0xF0, 0x90, 0x90, 0xA5, 0xF0, 0x90, - 0x90, 0xA6, 0xF0, 0x90, 0x90, 0xA7, - }, -}; - -#undef N_ -#undef FIL_ - -#ifdef __cplusplus -} -#endif - -#endif /* HAVE_UNICODE */ - -#endif /* _SYS_U8_TEXTPREP_DATA_H */ diff --git a/zfs/lib/libport/include/unistd.h b/zfs/lib/libport/include/unistd.h deleted file mode 100644 index b31e0ddfb..000000000 --- a/zfs/lib/libport/include/unistd.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include_next - -#ifndef _PORT_UNISTD_H -#define _PORT_UNISTD_H - -#include "zfs_config.h" - -#ifndef HAVE_ISSETUGID -#include -#define issetugid() (geteuid() == 0 || getegid() == 0) -#endif - -#ifdef HAVE_IOCTL_IN_UNISTD_H -#include -#endif - -#if !defined(__sun__) && !defined(__sun) -/* It seems Solaris only returns positive host ids */ -static inline long fake_gethostid() -{ - long id = gethostid(); - return id >= 0 ? id : -id; -} -#define gethostid() fake_gethostid() -#endif - -#endif /* _PORT_UNISTD_H */ diff --git a/zfs/lib/libport/port.c b/zfs/lib/libport/port.c deleted file mode 100644 index 904112588..000000000 --- a/zfs/lib/libport/port.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - -#include -#include -#include -#include - -#include "zfs_config.h" - -#ifndef HAVE_GETEXECNAME - -const char *getexecname() -{ -#ifdef __linux__ - static char execname[PATH_MAX + 1]; - /* Must be MT-safe */ - static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; - - pthread_mutex_lock(&mtx); - - if (strlen(execname) == 0) { - ssize_t rc = readlink("/proc/self/exe", execname, sizeof(execname - 1)); - if (rc == -1) { - execname[0] = '\0'; - pthread_mutex_unlock(&mtx); - return NULL; - } else - execname[rc] = '\0'; - } - pthread_mutex_unlock(&mtx); - - return execname; -#else - return NULL; -#endif -} - -#endif diff --git a/zfs/lib/libsolcompat/amd64/atomic.S b/zfs/lib/libsolcompat/amd64/atomic.S deleted file mode 100644 index cabccc1cf..000000000 --- a/zfs/lib/libsolcompat/amd64/atomic.S +++ /dev/null @@ -1,617 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - .ident "%Z%%M% %I% %E% SMI" - - .file "%M%" - -#define _ASM -#include - -#if defined(_KERNEL) - /* - * Legacy kernel interfaces; they will go away (eventually). - */ - ANSI_PRAGMA_WEAK2(cas8,atomic_cas_8,function) - ANSI_PRAGMA_WEAK2(cas32,atomic_cas_32,function) - ANSI_PRAGMA_WEAK2(cas64,atomic_cas_64,function) - ANSI_PRAGMA_WEAK2(caslong,atomic_cas_ulong,function) - ANSI_PRAGMA_WEAK2(casptr,atomic_cas_ptr,function) - ANSI_PRAGMA_WEAK2(atomic_and_long,atomic_and_ulong,function) - ANSI_PRAGMA_WEAK2(atomic_or_long,atomic_or_ulong,function) -#else - /* - * Include the definitions for the libc weak aliases. - */ -#include "../atomic_asm_weak.h" -#endif - - ENTRY(atomic_inc_8) - ALTENTRY(atomic_inc_uchar) - lock - incb (%rdi) - ret - SET_SIZE(atomic_inc_uchar) - SET_SIZE(atomic_inc_8) - - ENTRY(atomic_inc_16) - ALTENTRY(atomic_inc_ushort) - lock - incw (%rdi) - ret - SET_SIZE(atomic_inc_ushort) - SET_SIZE(atomic_inc_16) - - ENTRY(atomic_inc_32) - ALTENTRY(atomic_inc_uint) - lock - incl (%rdi) - ret - SET_SIZE(atomic_inc_uint) - SET_SIZE(atomic_inc_32) - - ENTRY(atomic_inc_64) - ALTENTRY(atomic_inc_ulong) - lock - incq (%rdi) - ret - SET_SIZE(atomic_inc_ulong) - SET_SIZE(atomic_inc_64) - - ENTRY(atomic_inc_8_nv) - ALTENTRY(atomic_inc_uchar_nv) - movb (%rdi), %al -1: - leaq 1(%rax), %rcx - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_inc_uchar_nv) - SET_SIZE(atomic_inc_8_nv) - - ENTRY(atomic_inc_16_nv) - ALTENTRY(atomic_inc_ushort_nv) - movw (%rdi), %ax -1: - leaq 1(%rax), %rcx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_inc_ushort_nv) - SET_SIZE(atomic_inc_16_nv) - - ENTRY(atomic_inc_32_nv) - ALTENTRY(atomic_inc_uint_nv) - movl (%rdi), %eax -1: - leaq 1(%rax), %rcx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_inc_uint_nv) - SET_SIZE(atomic_inc_32_nv) - - ENTRY(atomic_inc_64_nv) - ALTENTRY(atomic_inc_ulong_nv) - movq (%rdi), %rax -1: - leaq 1(%rax), %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_inc_ulong_nv) - SET_SIZE(atomic_inc_64_nv) - - ENTRY(atomic_dec_8) - ALTENTRY(atomic_dec_uchar) - lock - decb (%rdi) - ret - SET_SIZE(atomic_dec_uchar) - SET_SIZE(atomic_dec_8) - - ENTRY(atomic_dec_16) - ALTENTRY(atomic_dec_ushort) - lock - decw (%rdi) - ret - SET_SIZE(atomic_dec_ushort) - SET_SIZE(atomic_dec_16) - - ENTRY(atomic_dec_32) - ALTENTRY(atomic_dec_uint) - lock - decl (%rdi) - ret - SET_SIZE(atomic_dec_uint) - SET_SIZE(atomic_dec_32) - - ENTRY(atomic_dec_64) - ALTENTRY(atomic_dec_ulong) - lock - decq (%rdi) - ret - SET_SIZE(atomic_dec_ulong) - SET_SIZE(atomic_dec_64) - - ENTRY(atomic_dec_8_nv) - ALTENTRY(atomic_dec_uchar_nv) - movb (%rdi), %al -1: - leaq -1(%rax), %rcx - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_dec_uchar_nv) - SET_SIZE(atomic_dec_8_nv) - - ENTRY(atomic_dec_16_nv) - ALTENTRY(atomic_dec_ushort_nv) - movw (%rdi), %ax -1: - leaq -1(%rax), %rcx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_dec_ushort_nv) - SET_SIZE(atomic_dec_16_nv) - - ENTRY(atomic_dec_32_nv) - ALTENTRY(atomic_dec_uint_nv) - movl (%rdi), %eax -1: - leaq -1(%rax), %rcx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_dec_uint_nv) - SET_SIZE(atomic_dec_32_nv) - - ENTRY(atomic_dec_64_nv) - ALTENTRY(atomic_dec_ulong_nv) - movq (%rdi), %rax -1: - leaq -1(%rax), %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_dec_ulong_nv) - SET_SIZE(atomic_dec_64_nv) - - ENTRY(atomic_add_8) - ALTENTRY(atomic_add_char) - lock - addb %sil, (%rdi) - ret - SET_SIZE(atomic_add_char) - SET_SIZE(atomic_add_8) - - ENTRY(atomic_add_16) - ALTENTRY(atomic_add_short) - lock - addw %si, (%rdi) - ret - SET_SIZE(atomic_add_short) - SET_SIZE(atomic_add_16) - - ENTRY(atomic_add_32) - ALTENTRY(atomic_add_int) - lock - addl %esi, (%rdi) - ret - SET_SIZE(atomic_add_int) - SET_SIZE(atomic_add_32) - - ENTRY(atomic_add_64) - ALTENTRY(atomic_add_ptr) - ALTENTRY(atomic_add_long) - lock - addq %rsi, (%rdi) - ret - SET_SIZE(atomic_add_long) - SET_SIZE(atomic_add_ptr) - SET_SIZE(atomic_add_64) - - ENTRY(atomic_or_8) - ALTENTRY(atomic_or_uchar) - lock - orb %sil, (%rdi) - ret - SET_SIZE(atomic_or_uchar) - SET_SIZE(atomic_or_8) - - ENTRY(atomic_or_16) - ALTENTRY(atomic_or_ushort) - lock - orw %si, (%rdi) - ret - SET_SIZE(atomic_or_ushort) - SET_SIZE(atomic_or_16) - - ENTRY(atomic_or_32) - ALTENTRY(atomic_or_uint) - lock - orl %esi, (%rdi) - ret - SET_SIZE(atomic_or_uint) - SET_SIZE(atomic_or_32) - - ENTRY(atomic_or_64) - ALTENTRY(atomic_or_ulong) - lock - orq %rsi, (%rdi) - ret - SET_SIZE(atomic_or_ulong) - SET_SIZE(atomic_or_64) - - ENTRY(atomic_and_8) - ALTENTRY(atomic_and_uchar) - lock - andb %sil, (%rdi) - ret - SET_SIZE(atomic_and_uchar) - SET_SIZE(atomic_and_8) - - ENTRY(atomic_and_16) - ALTENTRY(atomic_and_ushort) - lock - andw %si, (%rdi) - ret - SET_SIZE(atomic_and_ushort) - SET_SIZE(atomic_and_16) - - ENTRY(atomic_and_32) - ALTENTRY(atomic_and_uint) - lock - andl %esi, (%rdi) - ret - SET_SIZE(atomic_and_uint) - SET_SIZE(atomic_and_32) - - ENTRY(atomic_and_64) - ALTENTRY(atomic_and_ulong) - lock - andq %rsi, (%rdi) - ret - SET_SIZE(atomic_and_ulong) - SET_SIZE(atomic_and_64) - - ENTRY(atomic_add_8_nv) - ALTENTRY(atomic_add_char_nv) - movb (%rdi), %al -1: - movb %sil, %cl - addb %al, %cl - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_add_char_nv) - SET_SIZE(atomic_add_8_nv) - - ENTRY(atomic_add_16_nv) - ALTENTRY(atomic_add_short_nv) - movw (%rdi), %ax -1: - movw %si, %cx - addw %ax, %cx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_add_short_nv) - SET_SIZE(atomic_add_16_nv) - - ENTRY(atomic_add_32_nv) - ALTENTRY(atomic_add_int_nv) - movl (%rdi), %eax -1: - movl %esi, %ecx - addl %eax, %ecx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_add_int_nv) - SET_SIZE(atomic_add_32_nv) - - ENTRY(atomic_add_64_nv) - ALTENTRY(atomic_add_ptr_nv) - ALTENTRY(atomic_add_long_nv) - movq (%rdi), %rax -1: - movq %rsi, %rcx - addq %rax, %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_add_long_nv) - SET_SIZE(atomic_add_ptr_nv) - SET_SIZE(atomic_add_64_nv) - - ENTRY(atomic_and_8_nv) - ALTENTRY(atomic_and_uchar_nv) - movb (%rdi), %al -1: - movb %sil, %cl - andb %al, %cl - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_and_uchar_nv) - SET_SIZE(atomic_and_8_nv) - - ENTRY(atomic_and_16_nv) - ALTENTRY(atomic_and_ushort_nv) - movw (%rdi), %ax -1: - movw %si, %cx - andw %ax, %cx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_and_ushort_nv) - SET_SIZE(atomic_and_16_nv) - - ENTRY(atomic_and_32_nv) - ALTENTRY(atomic_and_uint_nv) - movl (%rdi), %eax -1: - movl %esi, %ecx - andl %eax, %ecx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_and_uint_nv) - SET_SIZE(atomic_and_32_nv) - - ENTRY(atomic_and_64_nv) - ALTENTRY(atomic_and_ulong_nv) - movq (%rdi), %rax -1: - movq %rsi, %rcx - andq %rax, %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_and_ulong_nv) - SET_SIZE(atomic_and_64_nv) - - ENTRY(atomic_or_8_nv) - ALTENTRY(atomic_or_uchar_nv) - movb (%rdi), %al -1: - movb %sil, %cl - orb %al, %cl - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_and_uchar_nv) - SET_SIZE(atomic_and_8_nv) - - ENTRY(atomic_or_16_nv) - ALTENTRY(atomic_or_ushort_nv) - movw (%rdi), %ax -1: - movw %si, %cx - orw %ax, %cx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_or_ushort_nv) - SET_SIZE(atomic_or_16_nv) - - ENTRY(atomic_or_32_nv) - ALTENTRY(atomic_or_uint_nv) - movl (%rdi), %eax -1: - movl %esi, %ecx - orl %eax, %ecx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_or_uint_nv) - SET_SIZE(atomic_or_32_nv) - - ENTRY(atomic_or_64_nv) - ALTENTRY(atomic_or_ulong_nv) - movq (%rdi), %rax -1: - movq %rsi, %rcx - orq %rax, %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_or_ulong_nv) - SET_SIZE(atomic_or_64_nv) - - ENTRY(atomic_cas_8) - ALTENTRY(atomic_cas_uchar) - movzbl %sil, %eax - lock - cmpxchgb %dl, (%rdi) - ret - SET_SIZE(atomic_cas_uchar) - SET_SIZE(atomic_cas_8) - - ENTRY(atomic_cas_16) - ALTENTRY(atomic_cas_ushort) - movzwl %si, %eax - lock - cmpxchgw %dx, (%rdi) - ret - SET_SIZE(atomic_cas_ushort) - SET_SIZE(atomic_cas_16) - - ENTRY(atomic_cas_32) - ALTENTRY(atomic_cas_uint) - movl %esi, %eax - lock - cmpxchgl %edx, (%rdi) - ret - SET_SIZE(atomic_cas_uint) - SET_SIZE(atomic_cas_32) - - ENTRY(atomic_cas_64) - ALTENTRY(atomic_cas_ulong) - ALTENTRY(atomic_cas_ptr) - movq %rsi, %rax - lock - cmpxchgq %rdx, (%rdi) - ret - SET_SIZE(atomic_cas_ptr) - SET_SIZE(atomic_cas_ulong) - SET_SIZE(atomic_cas_64) - - ENTRY(atomic_swap_8) - ALTENTRY(atomic_swap_uchar) - movzbl %sil, %eax - lock - xchgb %al, (%rdi) - ret - SET_SIZE(atomic_swap_uchar) - SET_SIZE(atomic_swap_8) - - ENTRY(atomic_swap_16) - ALTENTRY(atomic_swap_ushort) - movzwl %si, %eax - lock - xchgw %ax, (%rdi) - ret - SET_SIZE(atomic_swap_ushort) - SET_SIZE(atomic_swap_16) - - ENTRY(atomic_swap_32) - ALTENTRY(atomic_swap_uint) - movl %esi, %eax - lock - xchgl %eax, (%rdi) - ret - SET_SIZE(atomic_swap_uint) - SET_SIZE(atomic_swap_32) - - ENTRY(atomic_swap_64) - ALTENTRY(atomic_swap_ulong) - ALTENTRY(atomic_swap_ptr) - movq %rsi, %rax - lock - xchgq %rax, (%rdi) - ret - SET_SIZE(atomic_swap_ptr) - SET_SIZE(atomic_swap_ulong) - SET_SIZE(atomic_swap_64) - - ENTRY(atomic_set_long_excl) - xorl %eax, %eax - lock - btsq %rsi, (%rdi) - jnc 1f - decl %eax -1: - ret - SET_SIZE(atomic_set_long_excl) - - ENTRY(atomic_clear_long_excl) - xorl %eax, %eax - lock - btrq %rsi, (%rdi) - jc 1f - decl %eax -1: - ret - SET_SIZE(atomic_clear_long_excl) - -#if !defined(_KERNEL) - - /* - * NOTE: membar_enter, and membar_exit are identical routines. - * We define them separately, instead of using an ALTENTRY - * definitions to alias them together, so that DTrace and - * debuggers will see a unique address for them, allowing - * more accurate tracing. - */ - - ENTRY(membar_enter) - mfence - ret - SET_SIZE(membar_enter) - - ENTRY(membar_exit) - mfence - ret - SET_SIZE(membar_exit) - - ENTRY(membar_producer) - sfence - ret - SET_SIZE(membar_producer) - - ENTRY(membar_consumer) - lfence - ret - SET_SIZE(membar_consumer) - -#endif /* !_KERNEL */ - -#ifdef __ELF__ -.section .note.GNU-stack,"",%progbits -#endif diff --git a/zfs/lib/libsolcompat/atomic_asm_weak.h b/zfs/lib/libsolcompat/atomic_asm_weak.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/gen_synonyms.h b/zfs/lib/libsolcompat/gen_synonyms.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/getmntany.c b/zfs/lib/libsolcompat/getmntany.c deleted file mode 100644 index 0c1e59257..000000000 --- a/zfs/lib/libsolcompat/getmntany.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Copyright 2006 Ricardo Correia. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ - -#include -#include -#include -#include - -#include -#include -#include - -#define BUFSIZE (MNT_LINE_MAX + 2) - -__thread char buf[BUFSIZE]; - -#define DIFF(xx) (mrefp->xx != NULL && (mgetp->xx == NULL || strcmp(mrefp->xx, mgetp->xx) != 0)) - -int -getmntany(FILE *fp, struct mnttab *mgetp, struct mnttab *mrefp) -{ - int ret; - - while ((ret = _sol_getmntent(fp, mgetp)) == 0 && (DIFF(mnt_special) || DIFF(mnt_mountp) || DIFF(mnt_fstype) || DIFF(mnt_mntopts))); - - return ret; -} - -int _sol_getmntent(FILE *fp, struct mnttab *mgetp) -{ - struct mntent mntbuf; - struct mntent *ret; - - ret = getmntent_r(fp, &mntbuf, buf, BUFSIZE); - - if(ret != NULL) { - mgetp->mnt_special = mntbuf.mnt_fsname; - mgetp->mnt_mountp = mntbuf.mnt_dir; - mgetp->mnt_fstype = mntbuf.mnt_type; - mgetp->mnt_mntopts = mntbuf.mnt_opts; - return 0; - } - - if(feof(fp)) - return -1; - - return MNT_TOOLONG; -} - -int getextmntent(FILE *fp, struct extmnttab *mp, int len) -{ - int ret; - struct stat64 st; - - ret = _sol_getmntent(fp, (struct mnttab *) mp); - if(ret == 0) { - if(stat64(mp->mnt_mountp, &st) != 0) { - mp->mnt_major = 0; - mp->mnt_minor = 0; - return ret; - } - mp->mnt_major = major(st.st_dev); - mp->mnt_minor = minor(st.st_dev); - } - - return ret; -} diff --git a/zfs/lib/libsolcompat/i386/atomic.S b/zfs/lib/libsolcompat/i386/atomic.S deleted file mode 100644 index 36c97abf8..000000000 --- a/zfs/lib/libsolcompat/i386/atomic.S +++ /dev/null @@ -1,752 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - .ident "%Z%%M% %I% %E% SMI" - - .file "%M%" - -#define _ASM -#include - -#if defined(_KERNEL) - /* - * Legacy kernel interfaces; they will go away (eventually). - */ - ANSI_PRAGMA_WEAK2(cas8,atomic_cas_8,function) - ANSI_PRAGMA_WEAK2(cas32,atomic_cas_32,function) - ANSI_PRAGMA_WEAK2(cas64,atomic_cas_64,function) - ANSI_PRAGMA_WEAK2(caslong,atomic_cas_ulong,function) - ANSI_PRAGMA_WEAK2(casptr,atomic_cas_ptr,function) - ANSI_PRAGMA_WEAK2(atomic_and_long,atomic_and_ulong,function) - ANSI_PRAGMA_WEAK2(atomic_or_long,atomic_or_ulong,function) -#else - /* - * Include the definitions for the libc weak aliases. - */ -#include "../atomic_asm_weak.h" -#endif - - ENTRY(atomic_inc_8) - ALTENTRY(atomic_inc_uchar) - movl 4(%esp), %eax - lock - incb (%eax) - ret - SET_SIZE(atomic_inc_uchar) - SET_SIZE(atomic_inc_8) - - ENTRY(atomic_inc_16) - ALTENTRY(atomic_inc_ushort) - movl 4(%esp), %eax - lock - incw (%eax) - ret - SET_SIZE(atomic_inc_ushort) - SET_SIZE(atomic_inc_16) - - ENTRY(atomic_inc_32) - ALTENTRY(atomic_inc_uint) - ALTENTRY(atomic_inc_ulong) - movl 4(%esp), %eax - lock - incl (%eax) - ret - SET_SIZE(atomic_inc_ulong) - SET_SIZE(atomic_inc_uint) - SET_SIZE(atomic_inc_32) - - ENTRY(atomic_inc_8_nv) - ALTENTRY(atomic_inc_uchar_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - leal 1(%eax), %ecx - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_inc_uchar_nv) - SET_SIZE(atomic_inc_8_nv) - - ENTRY(atomic_inc_16_nv) - ALTENTRY(atomic_inc_ushort_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - leal 1(%eax), %ecx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_inc_ushort_nv) - SET_SIZE(atomic_inc_16_nv) - - ENTRY(atomic_inc_32_nv) - ALTENTRY(atomic_inc_uint_nv) - ALTENTRY(atomic_inc_ulong_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - leal 1(%eax), %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_inc_ulong_nv) - SET_SIZE(atomic_inc_uint_nv) - SET_SIZE(atomic_inc_32_nv) - - /* - * NOTE: If atomic_inc_64 and atomic_inc_64_nv are ever - * separated, you need to also edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_inc_64_nv. - */ - ENTRY(atomic_inc_64) - ALTENTRY(atomic_inc_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - xorl %ebx, %ebx - xorl %ecx, %ecx - incl %ebx - addl %eax, %ebx - adcl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_inc_64_nv) - SET_SIZE(atomic_inc_64) - - ENTRY(atomic_dec_8) - ALTENTRY(atomic_dec_uchar) - movl 4(%esp), %eax - lock - decb (%eax) - ret - SET_SIZE(atomic_dec_uchar) - SET_SIZE(atomic_dec_8) - - ENTRY(atomic_dec_16) - ALTENTRY(atomic_dec_ushort) - movl 4(%esp), %eax - lock - decw (%eax) - ret - SET_SIZE(atomic_dec_ushort) - SET_SIZE(atomic_dec_16) - - ENTRY(atomic_dec_32) - ALTENTRY(atomic_dec_uint) - ALTENTRY(atomic_dec_ulong) - movl 4(%esp), %eax - lock - decl (%eax) - ret - SET_SIZE(atomic_dec_ulong) - SET_SIZE(atomic_dec_uint) - SET_SIZE(atomic_dec_32) - - ENTRY(atomic_dec_8_nv) - ALTENTRY(atomic_dec_uchar_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - leal -1(%eax), %ecx - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_dec_uchar_nv) - SET_SIZE(atomic_dec_8_nv) - - ENTRY(atomic_dec_16_nv) - ALTENTRY(atomic_dec_ushort_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - leal -1(%eax), %ecx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_dec_ushort_nv) - SET_SIZE(atomic_dec_16_nv) - - ENTRY(atomic_dec_32_nv) - ALTENTRY(atomic_dec_uint_nv) - ALTENTRY(atomic_dec_ulong_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - leal -1(%eax), %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_dec_ulong_nv) - SET_SIZE(atomic_dec_uint_nv) - SET_SIZE(atomic_dec_32_nv) - - /* - * NOTE: If atomic_dec_64 and atomic_dec_64_nv are ever - * separated, it is important to edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_dec_64_nv. - */ - ENTRY(atomic_dec_64) - ALTENTRY(atomic_dec_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - xorl %ebx, %ebx - xorl %ecx, %ecx - not %ecx - not %ebx - addl %eax, %ebx - adcl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_dec_64_nv) - SET_SIZE(atomic_dec_64) - - ENTRY(atomic_add_8) - ALTENTRY(atomic_add_char) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - addb %cl, (%eax) - ret - SET_SIZE(atomic_add_char) - SET_SIZE(atomic_add_8) - - ENTRY(atomic_add_16) - ALTENTRY(atomic_add_short) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - addw %cx, (%eax) - ret - SET_SIZE(atomic_add_short) - SET_SIZE(atomic_add_16) - - ENTRY(atomic_add_32) - ALTENTRY(atomic_add_int) - ALTENTRY(atomic_add_ptr) - ALTENTRY(atomic_add_long) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - addl %ecx, (%eax) - ret - SET_SIZE(atomic_add_long) - SET_SIZE(atomic_add_ptr) - SET_SIZE(atomic_add_int) - SET_SIZE(atomic_add_32) - - ENTRY(atomic_or_8) - ALTENTRY(atomic_or_uchar) - movl 4(%esp), %eax - movb 8(%esp), %cl - lock - orb %cl, (%eax) - ret - SET_SIZE(atomic_or_uchar) - SET_SIZE(atomic_or_8) - - ENTRY(atomic_or_16) - ALTENTRY(atomic_or_ushort) - movl 4(%esp), %eax - movw 8(%esp), %cx - lock - orw %cx, (%eax) - ret - SET_SIZE(atomic_or_ushort) - SET_SIZE(atomic_or_16) - - ENTRY(atomic_or_32) - ALTENTRY(atomic_or_uint) - ALTENTRY(atomic_or_ulong) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - orl %ecx, (%eax) - ret - SET_SIZE(atomic_or_ulong) - SET_SIZE(atomic_or_uint) - SET_SIZE(atomic_or_32) - - ENTRY(atomic_and_8) - ALTENTRY(atomic_and_uchar) - movl 4(%esp), %eax - movb 8(%esp), %cl - lock - andb %cl, (%eax) - ret - SET_SIZE(atomic_and_uchar) - SET_SIZE(atomic_and_8) - - ENTRY(atomic_and_16) - ALTENTRY(atomic_and_ushort) - movl 4(%esp), %eax - movw 8(%esp), %cx - lock - andw %cx, (%eax) - ret - SET_SIZE(atomic_and_ushort) - SET_SIZE(atomic_and_16) - - ENTRY(atomic_and_32) - ALTENTRY(atomic_and_uint) - ALTENTRY(atomic_and_ulong) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - andl %ecx, (%eax) - ret - SET_SIZE(atomic_and_ulong) - SET_SIZE(atomic_and_uint) - SET_SIZE(atomic_and_32) - - ENTRY(atomic_add_8_nv) - ALTENTRY(atomic_add_char_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - movl 8(%esp), %ecx - addb %al, %cl - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_add_char_nv) - SET_SIZE(atomic_add_8_nv) - - ENTRY(atomic_add_16_nv) - ALTENTRY(atomic_add_short_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - movl 8(%esp), %ecx - addw %ax, %cx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_add_short_nv) - SET_SIZE(atomic_add_16_nv) - - ENTRY(atomic_add_32_nv) - ALTENTRY(atomic_add_int_nv) - ALTENTRY(atomic_add_ptr_nv) - ALTENTRY(atomic_add_long_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - movl 8(%esp), %ecx - addl %eax, %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_add_long_nv) - SET_SIZE(atomic_add_ptr_nv) - SET_SIZE(atomic_add_int_nv) - SET_SIZE(atomic_add_32_nv) - - /* - * NOTE: If atomic_add_64 and atomic_add_64_nv are ever - * separated, it is important to edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_add_64_nv. - */ - ENTRY(atomic_add_64) - ALTENTRY(atomic_add_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - movl 16(%esp), %ebx - movl 20(%esp), %ecx - addl %eax, %ebx - adcl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_add_64_nv) - SET_SIZE(atomic_add_64) - - ENTRY(atomic_or_8_nv) - ALTENTRY(atomic_or_uchar_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - movl 8(%esp), %ecx - orb %al, %cl - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_or_uchar_nv) - SET_SIZE(atomic_or_8_nv) - - ENTRY(atomic_or_16_nv) - ALTENTRY(atomic_or_ushort_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - movl 8(%esp), %ecx - orw %ax, %cx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_or_ushort_nv) - SET_SIZE(atomic_or_16_nv) - - ENTRY(atomic_or_32_nv) - ALTENTRY(atomic_or_uint_nv) - ALTENTRY(atomic_or_ulong_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - movl 8(%esp), %ecx - orl %eax, %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_or_ulong_nv) - SET_SIZE(atomic_or_uint_nv) - SET_SIZE(atomic_or_32_nv) - - /* - * NOTE: If atomic_or_64 and atomic_or_64_nv are ever - * separated, it is important to edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_or_64_nv. - */ - ENTRY(atomic_or_64) - ALTENTRY(atomic_or_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - movl 16(%esp), %ebx - movl 20(%esp), %ecx - orl %eax, %ebx - orl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_or_64_nv) - SET_SIZE(atomic_or_64) - - ENTRY(atomic_and_8_nv) - ALTENTRY(atomic_and_uchar_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - movl 8(%esp), %ecx - andb %al, %cl - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_and_uchar_nv) - SET_SIZE(atomic_and_8_nv) - - ENTRY(atomic_and_16_nv) - ALTENTRY(atomic_and_ushort_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - movl 8(%esp), %ecx - andw %ax, %cx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_and_ushort_nv) - SET_SIZE(atomic_and_16_nv) - - ENTRY(atomic_and_32_nv) - ALTENTRY(atomic_and_uint_nv) - ALTENTRY(atomic_and_ulong_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - movl 8(%esp), %ecx - andl %eax, %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_and_ulong_nv) - SET_SIZE(atomic_and_uint_nv) - SET_SIZE(atomic_and_32_nv) - - /* - * NOTE: If atomic_and_64 and atomic_and_64_nv are ever - * separated, it is important to edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_and_64_nv. - */ - ENTRY(atomic_and_64) - ALTENTRY(atomic_and_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - movl 16(%esp), %ebx - movl 20(%esp), %ecx - andl %eax, %ebx - andl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_and_64_nv) - SET_SIZE(atomic_and_64) - - ENTRY(atomic_cas_8) - ALTENTRY(atomic_cas_uchar) - movl 4(%esp), %edx - movzbl 8(%esp), %eax - movb 12(%esp), %cl - lock - cmpxchgb %cl, (%edx) - ret - SET_SIZE(atomic_cas_uchar) - SET_SIZE(atomic_cas_8) - - ENTRY(atomic_cas_16) - ALTENTRY(atomic_cas_ushort) - movl 4(%esp), %edx - movzwl 8(%esp), %eax - movw 12(%esp), %cx - lock - cmpxchgw %cx, (%edx) - ret - SET_SIZE(atomic_cas_ushort) - SET_SIZE(atomic_cas_16) - - ENTRY(atomic_cas_32) - ALTENTRY(atomic_cas_uint) - ALTENTRY(atomic_cas_ulong) - ALTENTRY(atomic_cas_ptr) - movl 4(%esp), %edx - movl 8(%esp), %eax - movl 12(%esp), %ecx - lock - cmpxchgl %ecx, (%edx) - ret - SET_SIZE(atomic_cas_ptr) - SET_SIZE(atomic_cas_ulong) - SET_SIZE(atomic_cas_uint) - SET_SIZE(atomic_cas_32) - - ENTRY(atomic_cas_64) - pushl %ebx - pushl %esi - movl 12(%esp), %esi - movl 16(%esp), %eax - movl 20(%esp), %edx - movl 24(%esp), %ebx - movl 28(%esp), %ecx - lock - cmpxchg8b (%esi) - popl %esi - popl %ebx - ret - SET_SIZE(atomic_cas_64) - - ENTRY(atomic_swap_8) - ALTENTRY(atomic_swap_uchar) - movl 4(%esp), %edx - movzbl 8(%esp), %eax - lock - xchgb %al, (%edx) - ret - SET_SIZE(atomic_swap_uchar) - SET_SIZE(atomic_swap_8) - - ENTRY(atomic_swap_16) - ALTENTRY(atomic_swap_ushort) - movl 4(%esp), %edx - movzwl 8(%esp), %eax - lock - xchgw %ax, (%edx) - ret - SET_SIZE(atomic_swap_ushort) - SET_SIZE(atomic_swap_16) - - ENTRY(atomic_swap_32) - ALTENTRY(atomic_swap_uint) - ALTENTRY(atomic_swap_ptr) - ALTENTRY(atomic_swap_ulong) - movl 4(%esp), %edx - movl 8(%esp), %eax - lock - xchgl %eax, (%edx) - ret - SET_SIZE(atomic_swap_ulong) - SET_SIZE(atomic_swap_ptr) - SET_SIZE(atomic_swap_uint) - SET_SIZE(atomic_swap_32) - - ENTRY(atomic_swap_64) - pushl %esi - pushl %ebx - movl 12(%esp), %esi - movl 16(%esp), %ebx - movl 20(%esp), %ecx - movl (%esi), %eax - movl 4(%esi), %edx -1: - lock - cmpxchg8b (%esi) - jne 1b - popl %ebx - popl %esi - ret - SET_SIZE(atomic_swap_64) - - ENTRY(atomic_set_long_excl) - movl 4(%esp), %edx - movl 8(%esp), %ecx - xorl %eax, %eax - lock - btsl %ecx, (%edx) - jnc 1f - decl %eax -1: - ret - SET_SIZE(atomic_set_long_excl) - - ENTRY(atomic_clear_long_excl) - movl 4(%esp), %edx - movl 8(%esp), %ecx - xorl %eax, %eax - lock - btrl %ecx, (%edx) - jc 1f - decl %eax -1: - ret - SET_SIZE(atomic_clear_long_excl) - -#if !defined(_KERNEL) - - /* - * NOTE: membar_enter, membar_exit, membar_producer, and - * membar_consumer are all identical routines. We define them - * separately, instead of using ALTENTRY definitions to alias them - * together, so that DTrace and debuggers will see a unique address - * for them, allowing more accurate tracing. - */ - - - ENTRY(membar_enter) - lock - xorl $0, (%esp) - ret - SET_SIZE(membar_enter) - - ENTRY(membar_exit) - lock - xorl $0, (%esp) - ret - SET_SIZE(membar_exit) - - ENTRY(membar_producer) - lock - xorl $0, (%esp) - ret - SET_SIZE(membar_producer) - - ENTRY(membar_consumer) - lock - xorl $0, (%esp) - ret - SET_SIZE(membar_consumer) - -#endif /* !_KERNEL */ - -#ifdef __ELF__ -.section .note.GNU-stack,"",%progbits -#endif diff --git a/zfs/lib/libsolcompat/include/amd64/sys/asm_linkage.h b/zfs/lib/libsolcompat/include/amd64/sys/asm_linkage.h deleted file mode 100644 index d4b0c6ac7..000000000 --- a/zfs/lib/libsolcompat/include/amd64/sys/asm_linkage.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __amd64 -#define __amd64 -#endif - -#include diff --git a/zfs/lib/libsolcompat/include/assert.h b/zfs/lib/libsolcompat/include/assert.h deleted file mode 100644 index e53c134ca..000000000 --- a/zfs/lib/libsolcompat/include/assert.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_ASSERT_H -#define _SOL_ASSERT_H - -#include_next -#include -#include - -#ifndef __assert_c99 -static inline void __assert_c99(const char *expr, const char *file, int line, const char *func) -{ - fprintf(stderr, "%s:%i: %s: Assertion `%s` failed.\n", file, line, func, expr); - abort(); -} -#endif - -#endif diff --git a/zfs/lib/libsolcompat/include/atomic.h b/zfs/lib/libsolcompat/include/atomic.h deleted file mode 100644 index 8ce8f592d..000000000 --- a/zfs/lib/libsolcompat/include/atomic.h +++ /dev/null @@ -1,438 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ATOMIC_H -#define _SYS_ATOMIC_H - - - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_KERNEL) && defined(__GNUC__) && defined(_ASM_INLINES) && \ - (defined(__i386) || defined(__amd64)) -#include -#endif - -#if defined(_KERNEL) || defined(__STDC__) -/* - * Increment target. - */ -extern void atomic_inc_8(volatile uint8_t *); -extern void atomic_inc_uchar(volatile uchar_t *); -extern void atomic_inc_16(volatile uint16_t *); -extern void atomic_inc_ushort(volatile ushort_t *); -extern void atomic_inc_32(volatile uint32_t *); -extern void atomic_inc_uint(volatile uint_t *); -extern void atomic_inc_ulong(volatile ulong_t *); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern void atomic_inc_64(volatile uint64_t *); -#endif - -/* - * Decrement target - */ -extern void atomic_dec_8(volatile uint8_t *); -extern void atomic_dec_uchar(volatile uchar_t *); -extern void atomic_dec_16(volatile uint16_t *); -extern void atomic_dec_ushort(volatile ushort_t *); -extern void atomic_dec_32(volatile uint32_t *); -extern void atomic_dec_uint(volatile uint_t *); -extern void atomic_dec_ulong(volatile ulong_t *); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern void atomic_dec_64(volatile uint64_t *); -#endif - -/* - * Add delta to target - */ -extern void atomic_add_8(volatile uint8_t *, int8_t); -extern void atomic_add_char(volatile uchar_t *, signed char); -extern void atomic_add_16(volatile uint16_t *, int16_t); -extern void atomic_add_short(volatile ushort_t *, short); -extern void atomic_add_32(volatile uint32_t *, int32_t); -extern void atomic_add_int(volatile uint_t *, int); -extern void atomic_add_ptr(volatile void *, ssize_t); -extern void atomic_add_long(volatile ulong_t *, long); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern void atomic_add_64(volatile uint64_t *, int64_t); -#endif - -/* - * logical OR bits with target - */ -extern void atomic_or_8(volatile uint8_t *, uint8_t); -extern void atomic_or_uchar(volatile uchar_t *, uchar_t); -extern void atomic_or_16(volatile uint16_t *, uint16_t); -extern void atomic_or_ushort(volatile ushort_t *, ushort_t); -extern void atomic_or_32(volatile uint32_t *, uint32_t); -extern void atomic_or_uint(volatile uint_t *, uint_t); -extern void atomic_or_ulong(volatile ulong_t *, ulong_t); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern void atomic_or_64(volatile uint64_t *, uint64_t); -#endif - -/* - * logical AND bits with target - */ -extern void atomic_and_8(volatile uint8_t *, uint8_t); -extern void atomic_and_uchar(volatile uchar_t *, uchar_t); -extern void atomic_and_16(volatile uint16_t *, uint16_t); -extern void atomic_and_ushort(volatile ushort_t *, ushort_t); -extern void atomic_and_32(volatile uint32_t *, uint32_t); -extern void atomic_and_uint(volatile uint_t *, uint_t); -extern void atomic_and_ulong(volatile ulong_t *, ulong_t); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern void atomic_and_64(volatile uint64_t *, uint64_t); -#endif - -/* - * As above, but return the new value. Note that these _nv() variants are - * substantially more expensive on some platforms than the no-return-value - * versions above, so don't use them unless you really need to know the - * new value *atomically* (e.g. when decrementing a reference count and - * checking whether it went to zero). - */ - -/* - * Increment target and return new value. - */ -extern uint8_t atomic_inc_8_nv(volatile uint8_t *); -extern uchar_t atomic_inc_uchar_nv(volatile uchar_t *); -extern uint16_t atomic_inc_16_nv(volatile uint16_t *); -extern ushort_t atomic_inc_ushort_nv(volatile ushort_t *); -extern uint32_t atomic_inc_32_nv(volatile uint32_t *); -extern uint_t atomic_inc_uint_nv(volatile uint_t *); -extern ulong_t atomic_inc_ulong_nv(volatile ulong_t *); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern uint64_t atomic_inc_64_nv(volatile uint64_t *); -#endif - -/* - * Decrement target and return new value. - */ -extern uint8_t atomic_dec_8_nv(volatile uint8_t *); -extern uchar_t atomic_dec_uchar_nv(volatile uchar_t *); -extern uint16_t atomic_dec_16_nv(volatile uint16_t *); -extern ushort_t atomic_dec_ushort_nv(volatile ushort_t *); -extern uint32_t atomic_dec_32_nv(volatile uint32_t *); -extern uint_t atomic_dec_uint_nv(volatile uint_t *); -extern ulong_t atomic_dec_ulong_nv(volatile ulong_t *); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern uint64_t atomic_dec_64_nv(volatile uint64_t *); -#endif - -/* - * Add delta to target - */ -extern uint8_t atomic_add_8_nv(volatile uint8_t *, int8_t); -extern uchar_t atomic_add_char_nv(volatile uchar_t *, signed char); -extern uint16_t atomic_add_16_nv(volatile uint16_t *, int16_t); -extern ushort_t atomic_add_short_nv(volatile ushort_t *, short); -extern uint32_t atomic_add_32_nv(volatile uint32_t *, int32_t); -extern uint_t atomic_add_int_nv(volatile uint_t *, int); -extern void *atomic_add_ptr_nv(volatile void *, ssize_t); -extern ulong_t atomic_add_long_nv(volatile ulong_t *, long); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern uint64_t atomic_add_64_nv(volatile uint64_t *, int64_t); -#endif - -/* - * logical OR bits with target and return new value. - */ -extern uint8_t atomic_or_8_nv(volatile uint8_t *, uint8_t); -extern uchar_t atomic_or_uchar_nv(volatile uchar_t *, uchar_t); -extern uint16_t atomic_or_16_nv(volatile uint16_t *, uint16_t); -extern ushort_t atomic_or_ushort_nv(volatile ushort_t *, ushort_t); -extern uint32_t atomic_or_32_nv(volatile uint32_t *, uint32_t); -extern uint_t atomic_or_uint_nv(volatile uint_t *, uint_t); -extern ulong_t atomic_or_ulong_nv(volatile ulong_t *, ulong_t); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern uint64_t atomic_or_64_nv(volatile uint64_t *, uint64_t); -#endif - -/* - * logical AND bits with target and return new value. - */ -extern uint8_t atomic_and_8_nv(volatile uint8_t *, uint8_t); -extern uchar_t atomic_and_uchar_nv(volatile uchar_t *, uchar_t); -extern uint16_t atomic_and_16_nv(volatile uint16_t *, uint16_t); -extern ushort_t atomic_and_ushort_nv(volatile ushort_t *, ushort_t); -extern uint32_t atomic_and_32_nv(volatile uint32_t *, uint32_t); -extern uint_t atomic_and_uint_nv(volatile uint_t *, uint_t); -extern ulong_t atomic_and_ulong_nv(volatile ulong_t *, ulong_t); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern uint64_t atomic_and_64_nv(volatile uint64_t *, uint64_t); -#endif - -/* - * If *arg1 == arg2, set *arg1 = arg3; return old value - */ -extern uint8_t atomic_cas_8(volatile uint8_t *, uint8_t, uint8_t); -extern uchar_t atomic_cas_uchar(volatile uchar_t *, uchar_t, uchar_t); -extern uint16_t atomic_cas_16(volatile uint16_t *, uint16_t, uint16_t); -extern ushort_t atomic_cas_ushort(volatile ushort_t *, ushort_t, ushort_t); -extern uint32_t atomic_cas_32(volatile uint32_t *, uint32_t, uint32_t); -extern uint_t atomic_cas_uint(volatile uint_t *, uint_t, uint_t); -extern void *atomic_cas_ptr(volatile void *, void *, void *); -extern ulong_t atomic_cas_ulong(volatile ulong_t *, ulong_t, ulong_t); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern uint64_t atomic_cas_64(volatile uint64_t *, uint64_t, uint64_t); -#endif - -/* - * Swap target and return old value - */ -extern uint8_t atomic_swap_8(volatile uint8_t *, uint8_t); -extern uchar_t atomic_swap_uchar(volatile uchar_t *, uchar_t); -extern uint16_t atomic_swap_16(volatile uint16_t *, uint16_t); -extern ushort_t atomic_swap_ushort(volatile ushort_t *, ushort_t); -extern uint32_t atomic_swap_32(volatile uint32_t *, uint32_t); -extern uint_t atomic_swap_uint(volatile uint_t *, uint_t); -extern void *atomic_swap_ptr(volatile void *, void *); -extern ulong_t atomic_swap_ulong(volatile ulong_t *, ulong_t); -#if defined(_KERNEL) || defined(_INT64_TYPE) -extern uint64_t atomic_swap_64(volatile uint64_t *, uint64_t); -#endif - -/* - * Perform an exclusive atomic bit set/clear on a target. - * Returns 0 if bit was sucessfully set/cleared, or -1 - * if the bit was already set/cleared. - */ -extern int atomic_set_long_excl(volatile ulong_t *, uint_t); -extern int atomic_clear_long_excl(volatile ulong_t *, uint_t); - -/* - * Generic memory barrier used during lock entry, placed after the - * memory operation that acquires the lock to guarantee that the lock - * protects its data. No stores from after the memory barrier will - * reach visibility, and no loads from after the barrier will be - * resolved, before the lock acquisition reaches global visibility. - */ -extern void membar_enter(void); - -/* - * Generic memory barrier used during lock exit, placed before the - * memory operation that releases the lock to guarantee that the lock - * protects its data. All loads and stores issued before the barrier - * will be resolved before the subsequent lock update reaches visibility. - */ -extern void membar_exit(void); - -/* - * Arrange that all stores issued before this point in the code reach - * global visibility before any stores that follow; useful in producer - * modules that update a data item, then set a flag that it is available. - * The memory barrier guarantees that the available flag is not visible - * earlier than the updated data, i.e. it imposes store ordering. - */ -extern void membar_producer(void); - -/* - * Arrange that all loads issued before this point in the code are - * completed before any subsequent loads; useful in consumer modules - * that check to see if data is available and read the data. - * The memory barrier guarantees that the data is not sampled until - * after the available flag has been seen, i.e. it imposes load ordering. - */ -extern void membar_consumer(void); -#endif - -#if !defined(_KERNEL) && !defined(__STDC__) -extern void atomic_inc_8(); -extern void atomic_inc_uchar(); -extern void atomic_inc_16(); -extern void atomic_inc_ushort(); -extern void atomic_inc_32(); -extern void atomic_inc_uint(); -extern void atomic_inc_ulong(); -#if defined(_INT64_TYPE) -extern void atomic_inc_64(); -#endif /* defined(_INT64_TYPE) */ -extern void atomic_dec_8(); -extern void atomic_dec_uchar(); -extern void atomic_dec_16(); -extern void atomic_dec_ushort(); -extern void atomic_dec_32(); -extern void atomic_dec_uint(); -extern void atomic_dec_ulong(); -#if defined(_INT64_TYPE) -extern void atomic_dec_64(); -#endif /* defined(_INT64_TYPE) */ -extern void atomic_add_8(); -extern void atomic_add_char(); -extern void atomic_add_16(); -extern void atomic_add_short(); -extern void atomic_add_32(); -extern void atomic_add_int(); -extern void atomic_add_ptr(); -extern void atomic_add_long(); -#if defined(_INT64_TYPE) -extern void atomic_add_64(); -#endif /* defined(_INT64_TYPE) */ -extern void atomic_or_8(); -extern void atomic_or_uchar(); -extern void atomic_or_16(); -extern void atomic_or_ushort(); -extern void atomic_or_32(); -extern void atomic_or_uint(); -extern void atomic_or_ulong(); -#if defined(_INT64_TYPE) -extern void atomic_or_64(); -#endif /* defined(_INT64_TYPE) */ -extern void atomic_and_8(); -extern void atomic_and_uchar(); -extern void atomic_and_16(); -extern void atomic_and_ushort(); -extern void atomic_and_32(); -extern void atomic_and_uint(); -extern void atomic_and_ulong(); -#if defined(_INT64_TYPE) -extern void atomic_and_64(); -#endif /* defined(_INT64_TYPE) */ -extern uint8_t atomic_inc_8_nv(); -extern uchar_t atomic_inc_uchar_nv(); -extern uint16_t atomic_inc_16_nv(); -extern ushort_t atomic_inc_ushort_nv(); -extern uint32_t atomic_inc_32_nv(); -extern uint_t atomic_inc_uint_nv(); -extern ulong_t atomic_inc_ulong_nv(); -#if defined(_INT64_TYPE) -extern uint64_t atomic_inc_64_nv(); -#endif /* defined(_INT64_TYPE) */ -extern uint8_t atomic_dec_8_nv(); -extern uchar_t atomic_dec_uchar_nv(); -extern uint16_t atomic_dec_16_nv(); -extern ushort_t atomic_dec_ushort_nv(); -extern uint32_t atomic_dec_32_nv(); -extern uint_t atomic_dec_uint_nv(); -extern ulong_t atomic_dec_ulong_nv(); -#if defined(_INT64_TYPE) -extern uint64_t atomic_dec_64_nv(); -#endif /* defined(_INT64_TYPE) */ -extern uint8_t atomic_add_8_nv(); -extern uchar_t atomic_add_char_nv(); -extern uint16_t atomic_add_16_nv(); -extern ushort_t atomic_add_short_nv(); -extern uint32_t atomic_add_32_nv(); -extern uint_t atomic_add_int_nv(); -extern void *atomic_add_ptr_nv(); -extern ulong_t atomic_add_long_nv(); -#if defined(_INT64_TYPE) -extern uint64_t atomic_add_64_nv(); -#endif /* defined(_INT64_TYPE) */ -extern uint8_t atomic_or_8_nv(); -extern uchar_t atomic_or_uchar_nv(); -extern uint16_t atomic_or_16_nv(); -extern ushort_t atomic_or_ushort_nv(); -extern uint32_t atomic_or_32_nv(); -extern uint_t atomic_or_uint_nv(); -extern ulong_t atomic_or_ulong_nv(); -#if defined(_INT64_TYPE) -extern uint64_t atomic_or_64_nv(); -#endif /* defined(_INT64_TYPE) */ -extern uint8_t atomic_and_8_nv(); -extern uchar_t atomic_and_uchar_nv(); -extern uint16_t atomic_and_16_nv(); -extern ushort_t atomic_and_ushort_nv(); -extern uint32_t atomic_and_32_nv(); -extern uint_t atomic_and_uint_nv(); -extern ulong_t atomic_and_ulong_nv(); -#if defined(_INT64_TYPE) -extern uint64_t atomic_and_64_nv(); -#endif /* defined(_INT64_TYPE) */ -extern uint8_t atomic_cas_8(); -extern uchar_t atomic_cas_uchar(); -extern uint16_t atomic_cas_16(); -extern ushort_t atomic_cas_ushort(); -extern uint32_t atomic_cas_32(); -extern uint_t atomic_cas_uint(); -extern void *atomic_cas_ptr(); -extern ulong_t atomic_cas_ulong(); -#if defined(_INT64_TYPE) -extern uint64_t atomic_cas_64(); -#endif /* defined(_INT64_TYPE) */ -extern uint8_t atomic_swap_8(); -extern uchar_t atomic_swap_uchar(); -extern uint16_t atomic_swap_16(); -extern ushort_t atomic_swap_ushort(); -extern uint32_t atomic_swap_32(); -extern uint_t atomic_swap_uint(); -extern void *atomic_swap_ptr(); -extern ulong_t atomic_swap_ulong(); -#if defined(_INT64_TYPE) -extern uint64_t atomic_swap_64(); -#endif /* defined(_INT64_TYPE) */ - - -extern int atomic_set_long_excl(); -extern int atomic_clear_long_excl(); - -extern void membar_enter(); -extern void membar_exit(); -extern void membar_producer(); -extern void membar_consumer(); - -#endif - -#if defined(_KERNEL) - -#if defined(_LP64) || defined(_ILP32) -#define atomic_add_ip atomic_add_long -#define atomic_add_ip_nv atomic_add_long_nv -#define casip atomic_cas_ulong -#endif - -#if defined(__sparc) -extern uint8_t ldstub(uint8_t *); -#endif - -/* - * Legacy kernel interfaces; they will go away (eventually). - */ -extern uint8_t cas8(uint8_t *, uint8_t, uint8_t); -extern uint32_t cas32(uint32_t *, uint32_t, uint32_t); -extern uint64_t cas64(uint64_t *, uint64_t, uint64_t); -extern ulong_t caslong(ulong_t *, ulong_t, ulong_t); -extern void *casptr(void *, void *, void *); -extern void atomic_and_long(ulong_t *, ulong_t); -extern void atomic_or_long(ulong_t *, ulong_t); -#if defined(__sparc) -extern uint32_t swapl(uint32_t *, uint32_t); -#endif - -#endif /* _KERNEL */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_ATOMIC_H */ diff --git a/zfs/lib/libsolcompat/include/devid.h b/zfs/lib/libsolcompat/include/devid.h deleted file mode 100644 index 4f92fbe8d..000000000 --- a/zfs/lib/libsolcompat/include/devid.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _DEVID_H -#define _DEVID_H - -#include - -typedef int ddi_devid_t; - -typedef struct devid_nmlist { - char *devname; - dev_t dev; -} devid_nmlist_t; - -static inline int devid_str_decode(char *devidstr, ddi_devid_t *retdevid, char **retminor_name) { abort(); } -static inline int devid_deviceid_to_nmlist(char *search_path, ddi_devid_t devid, char *minor_name, devid_nmlist_t **retlist) { abort(); } -static inline void devid_str_free(char *str) { abort(); } -static inline void devid_free(ddi_devid_t devid) { abort(); } -static inline void devid_free_nmlist(devid_nmlist_t *list) { abort(); } -static inline int devid_get(int fd, ddi_devid_t *retdevid) { return -1; } -static inline int devid_get_minor_name(int fd, char **retminor_name) { abort(); } -static inline char *devid_str_encode(ddi_devid_t devid, char *minor_name) { abort(); } - -#endif diff --git a/zfs/lib/libsolcompat/include/dirent.h b/zfs/lib/libsolcompat/include/dirent.h deleted file mode 100644 index 3e78a491c..000000000 --- a/zfs/lib/libsolcompat/include/dirent.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_DIRENT_H -#define _SOL_DIRENT_H - -#include_next - -#ifdef IFTODT -#undef IFTODT -#endif - -#endif diff --git a/zfs/lib/libsolcompat/include/i386/sys/asm_linkage.h b/zfs/lib/libsolcompat/include/i386/sys/asm_linkage.h deleted file mode 100644 index 32ebbbfdc..000000000 --- a/zfs/lib/libsolcompat/include/i386/sys/asm_linkage.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __i386 -#define __i386 -#endif - -#include diff --git a/zfs/lib/libsolcompat/include/ia32/sys/asm_linkage.h b/zfs/lib/libsolcompat/include/ia32/sys/asm_linkage.h deleted file mode 100644 index 021ae1bea..000000000 --- a/zfs/lib/libsolcompat/include/ia32/sys/asm_linkage.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _IA32_SYS_ASM_LINKAGE_H -#define _IA32_SYS_ASM_LINKAGE_H - - - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _ASM /* The remainder of this file is only for assembly files */ - -/* - * make annoying differences in assembler syntax go away - */ - -/* - * D16 and A16 are used to insert instructions prefixes; the - * macros help the assembler code be slightly more portable. - */ -#if !defined(__GNUC_AS__) -/* - * /usr/ccs/bin/as prefixes are parsed as separate instructions - */ -#define D16 data16; -#define A16 addr16; - -/* - * (There are some weird constructs in constant expressions) - */ -#define _CONST(const) [const] -#define _BITNOT(const) -1!_CONST(const) -#define _MUL(a, b) _CONST(a \* b) - -#else -/* - * Why not use the 'data16' and 'addr16' prefixes .. well, the - * assembler doesn't quite believe in real mode, and thus argues with - * us about what we're trying to do. - */ -#define D16 .byte 0x66; -#define A16 .byte 0x67; - -#define _CONST(const) (const) -#define _BITNOT(const) ~_CONST(const) -#define _MUL(a, b) _CONST(a * b) - -#endif - -/* - * C pointers are different sizes between i386 and amd64. - * These constants can be used to compute offsets into pointer arrays. - */ -#if defined(__amd64) -#define CLONGSHIFT 3 -#define CLONGSIZE 8 -#define CLONGMASK 7 -#elif defined(__i386) -#define CLONGSHIFT 2 -#define CLONGSIZE 4 -#define CLONGMASK 3 -#endif - -/* - * Since we know we're either ILP32 or LP64 .. - */ -#define CPTRSHIFT CLONGSHIFT -#define CPTRSIZE CLONGSIZE -#define CPTRMASK CLONGMASK - -#if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT) -#error "inconsistent shift constants" -#endif - -#if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1) -#error "inconsistent mask constants" -#endif - -#define ASM_ENTRY_ALIGN 16 - -/* - * SSE register alignment and save areas - */ - -#define XMM_SIZE 16 -#define XMM_ALIGN 16 - -#if defined(__amd64) - -#define SAVE_XMM_PROLOG(sreg, nreg) \ - subq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp; \ - movq %rsp, sreg - -#define RSTOR_XMM_EPILOG(sreg, nreg) \ - addq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp - -#elif defined(__i386) - -#define SAVE_XMM_PROLOG(sreg, nreg) \ - subl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; \ - movl %esp, sreg; \ - addl $XMM_ALIGN, sreg; \ - andl $_BITNOT(XMM_ALIGN-1), sreg - -#define RSTOR_XMM_EPILOG(sreg, nreg) \ - addl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; - -#endif /* __i386 */ - -/* - * profiling causes definitions of the MCOUNT and RTMCOUNT - * particular to the type - */ -#ifdef GPROF - -#define MCOUNT(x) \ - pushl %ebp; \ - movl %esp, %ebp; \ - call _mcount; \ - popl %ebp - -#endif /* GPROF */ - -#ifdef PROF - -#define MCOUNT(x) \ -/* CSTYLED */ \ - .lcomm .L_/**/x/**/1, 4, 4; \ - pushl %ebp; \ - movl %esp, %ebp; \ -/* CSTYLED */ \ - movl $.L_/**/x/**/1, %edx; \ - call _mcount; \ - popl %ebp - -#endif /* PROF */ - -/* - * if we are not profiling, MCOUNT should be defined to nothing - */ -#if !defined(PROF) && !defined(GPROF) -#define MCOUNT(x) -#endif /* !defined(PROF) && !defined(GPROF) */ - -#define RTMCOUNT(x) MCOUNT(x) - -/* - * Macro to define weak symbol aliases. These are similar to the ANSI-C - * #pragma weak name = _name - * except a compiler can determine type. The assembler must be told. Hence, - * the second parameter must be the type of the symbol (i.e.: function,...) - */ -#define ANSI_PRAGMA_WEAK(sym, stype) \ - .weak sym; \ - .type sym, @stype; \ -/* CSTYLED */ \ -sym = _/**/sym - -/* - * Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in: - * #pragma weak sym1 = sym2 - */ -#define ANSI_PRAGMA_WEAK2(sym1, sym2, stype) \ - .weak sym1; \ - .type sym1, @stype; \ -sym1 = sym2 - -/* - * ENTRY provides the standard procedure entry code and an easy way to - * insert the calls to mcount for profiling. ENTRY_NP is identical, but - * never calls mcount. - */ -#define ENTRY(x) \ - .text; \ - .align ASM_ENTRY_ALIGN; \ - .globl x; \ - .type x, @function; \ -x: MCOUNT(x) - -#define ENTRY_NP(x) \ - .text; \ - .align ASM_ENTRY_ALIGN; \ - .globl x; \ - .type x, @function; \ -x: - -#define RTENTRY(x) \ - .text; \ - .align ASM_ENTRY_ALIGN; \ - .globl x; \ - .type x, @function; \ -x: RTMCOUNT(x) - -/* - * ENTRY2 is identical to ENTRY but provides two labels for the entry point. - */ -#define ENTRY2(x, y) \ - .text; \ - .align ASM_ENTRY_ALIGN; \ - .globl x, y; \ - .type x, @function; \ - .type y, @function; \ -/* CSTYLED */ \ -x: ; \ -y: MCOUNT(x) - -#define ENTRY_NP2(x, y) \ - .text; \ - .align ASM_ENTRY_ALIGN; \ - .globl x, y; \ - .type x, @function; \ - .type y, @function; \ -/* CSTYLED */ \ -x: ; \ -y: - - -/* - * ALTENTRY provides for additional entry points. - */ -#define ALTENTRY(x) \ - .globl x; \ - .type x, @function; \ -x: - -/* - * DGDEF and DGDEF2 provide global data declarations. - * - * DGDEF provides a word aligned word of storage. - * - * DGDEF2 allocates "sz" bytes of storage with **NO** alignment. This - * implies this macro is best used for byte arrays. - * - * DGDEF3 allocates "sz" bytes of storage with "algn" alignment. - */ -#define DGDEF2(name, sz) \ - .data; \ - .globl name; \ - .type name, @object; \ - .size name, sz; \ -name: - -#define DGDEF3(name, sz, algn) \ - .data; \ - .align algn; \ - .globl name; \ - .type name, @object; \ - .size name, sz; \ -name: - -#define DGDEF(name) DGDEF3(name, 4, 4) - -/* - * SET_SIZE trails a function and set the size for the ELF symbol table. - */ -#define SET_SIZE(x) \ - .size x, [.-x] - -/* - * NWORD provides native word value. - */ -#if defined(__amd64) - -/*CSTYLED*/ -#define NWORD quad - -#elif defined(__i386) - -#define NWORD long - -#endif /* __i386 */ - -#endif /* _ASM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _IA32_SYS_ASM_LINKAGE_H */ diff --git a/zfs/lib/libsolcompat/include/libc.h b/zfs/lib/libsolcompat/include/libc.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/libdevinfo.h b/zfs/lib/libsolcompat/include/libdevinfo.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/libgen.h b/zfs/lib/libsolcompat/include/libgen.h deleted file mode 100644 index 203670f0d..000000000 --- a/zfs/lib/libsolcompat/include/libgen.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_LIBGEN_H -#define _SOL_LIBGEN_H - -#include_next -#include - -extern int mkdirp(const char *path, mode_t mode); - -#endif diff --git a/zfs/lib/libsolcompat/include/mtlib.h b/zfs/lib/libsolcompat/include/mtlib.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/priv.h b/zfs/lib/libsolcompat/include/priv.h deleted file mode 100644 index 873502b4f..000000000 --- a/zfs/lib/libsolcompat/include/priv.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PRIV_H -#define _PRIV_H - -#include - -/* Couldn't find this definition in OpenGrok */ -#define PRIV_SYS_CONFIG "sys_config" - -static inline boolean_t priv_ineffect(const char *priv) { return B_TRUE; } - -#endif diff --git a/zfs/lib/libsolcompat/include/rpc/xdr.h b/zfs/lib/libsolcompat/include/rpc/xdr.h deleted file mode 100644 index b5c836fd5..000000000 --- a/zfs/lib/libsolcompat/include/rpc/xdr.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * Portions of this source code were derived from Berkeley 4.3 BSD - * under license from the Regents of the University of California. - */ - -#ifndef _SOL_RPC_XDR_H_ -#define _SOL_RPC_XDR_H_ - -#include_next - -/* - * Strangely, my glibc version (2.3.6) doesn't have xdr_control(), so - * we have to hack it in here (source taken from OpenSolaris). - * By the way, it is assumed the xdrmem implementation is used. - */ - -#define xdr_control(a,b,c) xdrmem_control(a,b,c) - -/* - * These are XDR control operators - */ - -#define XDR_GET_BYTES_AVAIL 1 - -struct xdr_bytesrec { - bool_t xc_is_last_record; - size_t xc_num_avail; -}; - -typedef struct xdr_bytesrec xdr_bytesrec; - -/* - * These are the request arguments to XDR_CONTROL. - * - * XDR_PEEK - returns the contents of the next XDR unit on the XDR stream. - * XDR_SKIPBYTES - skips the next N bytes in the XDR stream. - * XDR_RDMAGET - for xdr implementation over RDMA, gets private flags from - * the XDR stream being moved over RDMA - * XDR_RDMANOCHUNK - for xdr implementaion over RDMA, sets private flags in - * the XDR stream moving over RDMA. - */ -#define XDR_PEEK 2 -#define XDR_SKIPBYTES 3 -#define XDR_RDMAGET 4 -#define XDR_RDMASET 5 - -/* FIXME: probably doesn't work */ -static bool_t -xdrmem_control(XDR *xdrs, int request, void *info) -{ - xdr_bytesrec *xptr; - int32_t *int32p; - int len; - - switch (request) { - - case XDR_GET_BYTES_AVAIL: - xptr = (xdr_bytesrec *)info; - xptr->xc_is_last_record = TRUE; - xptr->xc_num_avail = xdrs->x_handy; - return (TRUE); - - case XDR_PEEK: - /* - * Return the next 4 byte unit in the XDR stream. - */ - if (xdrs->x_handy < sizeof (int32_t)) - return (FALSE); - int32p = (int32_t *)info; - *int32p = (int32_t)ntohl((uint32_t) - (*((int32_t *)(xdrs->x_private)))); - return (TRUE); - - case XDR_SKIPBYTES: - /* - * Skip the next N bytes in the XDR stream. - */ - int32p = (int32_t *)info; - len = RNDUP((int)(*int32p)); - if ((xdrs->x_handy -= len) < 0) - return (FALSE); - xdrs->x_private += len; - return (TRUE); - - } - return (FALSE); -} - -#endif diff --git a/zfs/lib/libsolcompat/include/sparc64/sys/asm_linkage.h b/zfs/lib/libsolcompat/include/sparc64/sys/asm_linkage.h deleted file mode 100644 index 7ec892e9e..000000000 --- a/zfs/lib/libsolcompat/include/sparc64/sys/asm_linkage.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ASM_LINKAGE_H -#define _SYS_ASM_LINKAGE_H - - - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _ASM /* The remainder of this file is only for assembly files */ - -/* - * C pointers are different sizes between V8 and V9. - * These constants can be used to compute offsets into pointer arrays. - */ -#ifdef __sparcv9 -#define CPTRSHIFT 3 -#define CLONGSHIFT 3 -#else -#define CPTRSHIFT 2 -#define CLONGSHIFT 2 -#endif -#define CPTRSIZE (1< - -#ifndef _SOL_STDARG_H -#define _SOL_STDARG_H - -#ifndef __va_list -typedef __gnuc_va_list __va_list; -#endif - -#endif diff --git a/zfs/lib/libsolcompat/include/stdio_ext.h b/zfs/lib/libsolcompat/include/stdio_ext.h deleted file mode 100644 index 839e05f7e..000000000 --- a/zfs/lib/libsolcompat/include/stdio_ext.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _STDIO_EXT_H -#define _STDIO_EXT_H - -#define enable_extended_FILE_stdio(x,y) (0) - -#endif diff --git a/zfs/lib/libsolcompat/include/strings.h b/zfs/lib/libsolcompat/include/strings.h deleted file mode 100644 index a6d5ffa95..000000000 --- a/zfs/lib/libsolcompat/include/strings.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_STRINGS_H -#define _SOL_STRINGS_H - -#include -#include_next - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/acl.h b/zfs/lib/libsolcompat/include/sys/acl.h deleted file mode 100644 index a47ce49af..000000000 --- a/zfs/lib/libsolcompat/include/sys/acl.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ACL_H -#define _SYS_ACL_H - - - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_ACL_ENTRIES (1024) /* max entries of each type */ -typedef struct acl { - int a_type; /* the type of ACL entry */ - uid_t a_id; /* the entry in -uid or gid */ - o_mode_t a_perm; /* the permission field */ -} aclent_t; - -typedef struct ace { - uid_t a_who; /* uid or gid */ - uint32_t a_access_mask; /* read,write,... */ - uint16_t a_flags; /* see below */ - uint16_t a_type; /* allow or deny */ -} ace_t; - -typedef struct acl_info acl_t; - -/* - * The following are Defined types for an aclent_t. - */ -#define USER_OBJ (0x01) /* object owner */ -#define USER (0x02) /* additional users */ -#define GROUP_OBJ (0x04) /* owning group of the object */ -#define GROUP (0x08) /* additional groups */ -#define CLASS_OBJ (0x10) /* file group class and mask entry */ -#define OTHER_OBJ (0x20) /* other entry for the object */ -#define ACL_DEFAULT (0x1000) /* default flag */ -/* default object owner */ -#define DEF_USER_OBJ (ACL_DEFAULT | USER_OBJ) -/* default additional users */ -#define DEF_USER (ACL_DEFAULT | USER) -/* default owning group */ -#define DEF_GROUP_OBJ (ACL_DEFAULT | GROUP_OBJ) -/* default additional groups */ -#define DEF_GROUP (ACL_DEFAULT | GROUP) -/* default mask entry */ -#define DEF_CLASS_OBJ (ACL_DEFAULT | CLASS_OBJ) -/* default other entry */ -#define DEF_OTHER_OBJ (ACL_DEFAULT | OTHER_OBJ) - -/* - * The following are defined for ace_t. - */ -#define ACE_READ_DATA 0x00000001 -#define ACE_LIST_DIRECTORY 0x00000001 -#define ACE_WRITE_DATA 0x00000002 -#define ACE_ADD_FILE 0x00000002 -#define ACE_APPEND_DATA 0x00000004 -#define ACE_ADD_SUBDIRECTORY 0x00000004 -#define ACE_READ_NAMED_ATTRS 0x00000008 -#define ACE_WRITE_NAMED_ATTRS 0x00000010 -#define ACE_EXECUTE 0x00000020 -#define ACE_DELETE_CHILD 0x00000040 -#define ACE_READ_ATTRIBUTES 0x00000080 -#define ACE_WRITE_ATTRIBUTES 0x00000100 -#define ACE_DELETE 0x00010000 -#define ACE_READ_ACL 0x00020000 -#define ACE_WRITE_ACL 0x00040000 -#define ACE_WRITE_OWNER 0x00080000 -#define ACE_SYNCHRONIZE 0x00100000 - -#define ACE_FILE_INHERIT_ACE 0x0001 -#define ACE_DIRECTORY_INHERIT_ACE 0x0002 -#define ACE_NO_PROPAGATE_INHERIT_ACE 0x0004 -#define ACE_INHERIT_ONLY_ACE 0x0008 -#define ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x0010 -#define ACE_FAILED_ACCESS_ACE_FLAG 0x0020 -#define ACE_IDENTIFIER_GROUP 0x0040 -#define ACE_INHERITED_ACE 0x0080 -#define ACE_OWNER 0x1000 -#define ACE_GROUP 0x2000 -#define ACE_EVERYONE 0x4000 - -#define ACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 -#define ACE_ACCESS_DENIED_ACE_TYPE 0x0001 -#define ACE_SYSTEM_AUDIT_ACE_TYPE 0x0002 -#define ACE_SYSTEM_ALARM_ACE_TYPE 0x0003 - -#define ACL_AUTO_INHERIT 0x0001 -#define ACL_PROTECTED 0x0002 -#define ACL_DEFAULTED 0x0004 -#define ACL_FLAGS_ALL (ACL_AUTO_INHERIT|ACL_PROTECTED| \ - ACL_DEFAULTED) - -#ifdef _KERNEL - -/* - * These are only applicable in a CIFS context. - */ -#define ACE_ACCESS_ALLOWED_COMPOUND_ACE_TYPE 0x04 -#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05 -#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06 -#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07 -#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08 -#define ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE 0x09 -#define ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE 0x0A -#define ACE_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE 0x0B -#define ACE_ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE 0x0C -#define ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE 0x0D -#define ACE_SYSTEM_ALARM_CALLBACK_ACE_TYPE 0x0E -#define ACE_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE 0x0F -#define ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE 0x10 - -#define ACE_ALL_TYPES 0x001F - -typedef struct ace_object { - uid_t a_who; /* uid or gid */ - uint32_t a_access_mask; /* read,write,... */ - uint16_t a_flags; /* see below */ - uint16_t a_type; /* allow or deny */ - uint8_t a_obj_type[16]; /* obj type */ - uint8_t a_inherit_obj_type[16]; /* inherit obj */ -} ace_object_t; - -#endif - -#define ACE_ALL_PERMS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ - ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_READ_NAMED_ATTRS| \ - ACE_WRITE_NAMED_ATTRS|ACE_EXECUTE|ACE_DELETE_CHILD|ACE_READ_ATTRIBUTES| \ - ACE_WRITE_ATTRIBUTES|ACE_DELETE|ACE_READ_ACL|ACE_WRITE_ACL| \ - ACE_WRITE_OWNER|ACE_SYNCHRONIZE) - -/* - * The following flags are supported by both NFSv4 ACLs and ace_t. - */ -#define ACE_NFSV4_SUP_FLAGS (ACE_FILE_INHERIT_ACE | \ - ACE_DIRECTORY_INHERIT_ACE | \ - ACE_NO_PROPAGATE_INHERIT_ACE | \ - ACE_INHERIT_ONLY_ACE | \ - ACE_IDENTIFIER_GROUP) - -#define ACE_TYPE_FLAGS (ACE_OWNER|ACE_GROUP|ACE_EVERYONE| \ - ACE_IDENTIFIER_GROUP) -#define ACE_INHERIT_FLAGS (ACE_FILE_INHERIT_ACE| \ - ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE) - -/* cmd args to acl(2) for aclent_t */ -#define GETACL 1 -#define SETACL 2 -#define GETACLCNT 3 - -/* cmd's to manipulate ace acls. */ -#define ACE_GETACL 4 -#define ACE_SETACL 5 -#define ACE_GETACLCNT 6 - -/* minimal acl entries from GETACLCNT */ -#define MIN_ACL_ENTRIES 4 - -#if !defined(_KERNEL) - -/* acl check errors */ -#define GRP_ERROR 1 -#define USER_ERROR 2 -#define OTHER_ERROR 3 -#define CLASS_ERROR 4 -#define DUPLICATE_ERROR 5 -#define MISS_ERROR 6 -#define MEM_ERROR 7 -#define ENTRY_ERROR 8 - - -/* - * similar to ufs_acl.h: changed to char type for user commands (tar, cpio) - * Attribute types - */ -#define UFSD_FREE ('0') /* Free entry */ -#define UFSD_ACL ('1') /* Access Control Lists */ -#define UFSD_DFACL ('2') /* reserved for future use */ -#define ACE_ACL ('3') /* ace_t style acls */ - -/* - * flag to [f]acl_get() - * controls whether a trivial acl should be returned. - */ -#define ACL_NO_TRIVIAL 0x2 - - -/* - * Flags to control acl_totext() - */ - -#define ACL_APPEND_ID 0x1 /* append uid/gid to user/group entries */ -#define ACL_COMPACT_FMT 0x2 /* build ACL in ls -V format */ -#define ACL_NORESOLVE 0x4 /* don't do name service lookups */ - -/* - * Legacy aclcheck errors for aclent_t ACLs - */ -#define EACL_GRP_ERROR GRP_ERROR -#define EACL_USER_ERROR USER_ERROR -#define EACL_OTHER_ERROR OTHER_ERROR -#define EACL_CLASS_ERROR CLASS_ERROR -#define EACL_DUPLICATE_ERROR DUPLICATE_ERROR -#define EACL_MISS_ERROR MISS_ERROR -#define EACL_MEM_ERROR MEM_ERROR -#define EACL_ENTRY_ERROR ENTRY_ERROR - -#define EACL_INHERIT_ERROR 9 /* invalid inherit flags */ -#define EACL_FLAGS_ERROR 10 /* unknown flag value */ -#define EACL_PERM_MASK_ERROR 11 /* unknown permission */ -#define EACL_COUNT_ERROR 12 /* invalid acl count */ - -#define EACL_INVALID_SLOT 13 /* invalid acl slot */ -#define EACL_NO_ACL_ENTRY 14 /* Entry doesn't exist */ -#define EACL_DIFF_TYPE 15 /* acls aren't same type */ - -#define EACL_INVALID_USER_GROUP 16 /* need user/group name */ -#define EACL_INVALID_STR 17 /* invalid acl string */ -#define EACL_FIELD_NOT_BLANK 18 /* can't have blank field */ -#define EACL_INVALID_ACCESS_TYPE 19 /* invalid access type */ -#define EACL_UNKNOWN_DATA 20 /* Unrecognized data in ACL */ -#define EACL_MISSING_FIELDS 21 /* missing fields in acl */ - -#define EACL_INHERIT_NOTDIR 22 /* Need dir for inheritance */ - -extern int aclcheck(aclent_t *, int, int *); -extern int acltomode(aclent_t *, int, mode_t *); -extern int aclfrommode(aclent_t *, int, mode_t *); -extern int aclsort(int, int, aclent_t *); -extern char *acltotext(aclent_t *, int); -extern aclent_t *aclfromtext(char *, int *); -extern void acl_free(acl_t *); -extern int acl_get(const char *, int, acl_t **); -extern int facl_get(int, int, acl_t **); -extern int acl_set(const char *, acl_t *acl); -extern int facl_set(int, acl_t *acl); -extern int acl_strip(const char *, uid_t, gid_t, mode_t); -extern int acl_trivial(const char *); -extern char *acl_totext(acl_t *, int); -extern int acl_fromtext(const char *, acl_t **); -extern int acl_check(acl_t *, int); - -#else /* !defined(_KERNEL) */ - -extern void ksort(caddr_t, int, int, int (*)(void *, void *)); -extern int cmp2acls(void *, void *); - -#endif /* !defined(_KERNEL) */ - -#if defined(__STDC__) -extern int acl(const char *path, int cmd, int cnt, void *buf); -extern int facl(int fd, int cmd, int cnt, void *buf); -#else /* !__STDC__ */ -extern int acl(); -extern int facl(); -#endif /* defined(__STDC__) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_ACL_H */ diff --git a/zfs/lib/libsolcompat/include/sys/acl_impl.h b/zfs/lib/libsolcompat/include/sys/acl_impl.h deleted file mode 100644 index 5f8f01f2e..000000000 --- a/zfs/lib/libsolcompat/include/sys/acl_impl.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ACL_IMPL_H -#define _SYS_ACL_IMPL_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * acl flags - * - * ACL_AUTO_INHERIT, ACL_PROTECTED and ACL_DEFAULTED - * flags can also be stored in this field. - */ -#define ACL_IS_TRIVIAL 0x10000 -#define ACL_IS_DIR 0x20000 - -typedef enum acl_type { - ACLENT_T = 0, - ACE_T = 1 -} acl_type_t; - -struct acl_info { - acl_type_t acl_type; /* style of acl */ - int acl_cnt; /* number of acl entries */ - int acl_entry_size; /* sizeof acl entry */ - int acl_flags; /* special flags about acl */ - void *acl_aclp; /* the acl */ -}; - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_ACL_IMPL_H */ diff --git a/zfs/lib/libsolcompat/include/sys/bitmap.h b/zfs/lib/libsolcompat/include/sys/bitmap.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/byteorder.h b/zfs/lib/libsolcompat/include/sys/byteorder.h deleted file mode 100644 index 528d2d208..000000000 --- a/zfs/lib/libsolcompat/include/sys/byteorder.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#ifndef _SYS_BYTEORDER_H -#define _SYS_BYTEORDER_H - - - -#include -#include - -#if defined(__GNUC__) && defined(_ASM_INLINES) && \ - (defined(__i386) || defined(__amd64)) -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * macros for conversion between host and (internet) network byte order - */ - -#if defined(_BIG_ENDIAN) && !defined(ntohl) && !defined(__lint) -/* big-endian */ -#define ntohl(x) (x) -#define ntohs(x) (x) -#define htonl(x) (x) -#define htons(x) (x) - -#elif !defined(ntohl) /* little-endian */ - -#ifndef _IN_PORT_T -#define _IN_PORT_T -typedef uint16_t in_port_t; -#endif - -#ifndef _IN_ADDR_T -#define _IN_ADDR_T -typedef uint32_t in_addr_t; -#endif - -#if !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) -extern uint32_t htonl(uint32_t); -extern uint16_t htons(uint16_t); -extern uint32_t ntohl(uint32_t); -extern uint16_t ntohs(uint16_t); -#else -extern in_addr_t htonl(in_addr_t); -extern in_port_t htons(in_port_t); -extern in_addr_t ntohl(in_addr_t); -extern in_port_t ntohs(in_port_t); -#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) */ -#endif - -#if !defined(_XPG4_2) || defined(__EXTENSIONS__) - -/* - * Macros to reverse byte order - */ -#define BSWAP_8(x) ((x) & 0xff) -#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8)) -#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16)) -#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32)) - -#define BMASK_8(x) ((x) & 0xff) -#define BMASK_16(x) ((x) & 0xffff) -#define BMASK_32(x) ((x) & 0xffffffff) -#define BMASK_64(x) (x) - -/* - * Macros to convert from a specific byte order to/from native byte order - */ -#ifdef _BIG_ENDIAN -#define BE_8(x) BMASK_8(x) -#define BE_16(x) BMASK_16(x) -#define BE_32(x) BMASK_32(x) -#define BE_64(x) BMASK_64(x) -#define LE_8(x) BSWAP_8(x) -#define LE_16(x) BSWAP_16(x) -#define LE_32(x) BSWAP_32(x) -#define LE_64(x) BSWAP_64(x) -#else -#define LE_8(x) BMASK_8(x) -#define LE_16(x) BMASK_16(x) -#define LE_32(x) BMASK_32(x) -#define LE_64(x) BMASK_64(x) -#define BE_8(x) BSWAP_8(x) -#define BE_16(x) BSWAP_16(x) -#define BE_32(x) BSWAP_32(x) -#define BE_64(x) BSWAP_64(x) -#endif - -/* - * Macros to read unaligned values from a specific byte order to - * native byte order - */ - -#define BE_IN8(xa) \ - *((uint8_t *)(xa)) - -#define BE_IN16(xa) \ - (((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1)) - -#define BE_IN32(xa) \ - (((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2)) - -#define BE_IN64(xa) \ - (((uint64_t)BE_IN32(xa) << 32) | BE_IN32((uint8_t *)(xa)+4)) - -#define LE_IN8(xa) \ - *((uint8_t *)(xa)) - -#define LE_IN16(xa) \ - (((uint16_t)LE_IN8((uint8_t *)(xa) + 1) << 8) | LE_IN8(xa)) - -#define LE_IN32(xa) \ - (((uint32_t)LE_IN16((uint8_t *)(xa) + 2) << 16) | LE_IN16(xa)) - -#define LE_IN64(xa) \ - (((uint64_t)LE_IN32((uint8_t *)(xa) + 4) << 32) | LE_IN32(xa)) - -/* - * Macros to write unaligned values from native byte order to a specific byte - * order. - */ - -#define BE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv); - -#define BE_OUT16(xa, yv) \ - BE_OUT8((uint8_t *)(xa) + 1, yv); \ - BE_OUT8((uint8_t *)(xa), (yv) >> 8); - -#define BE_OUT32(xa, yv) \ - BE_OUT16((uint8_t *)(xa) + 2, yv); \ - BE_OUT16((uint8_t *)(xa), (yv) >> 16); - -#define BE_OUT64(xa, yv) \ - BE_OUT32((uint8_t *)(xa) + 4, yv); \ - BE_OUT32((uint8_t *)(xa), (yv) >> 32); - -#define LE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv); - -#define LE_OUT16(xa, yv) \ - LE_OUT8((uint8_t *)(xa), yv); \ - LE_OUT8((uint8_t *)(xa) + 1, (yv) >> 8); - -#define LE_OUT32(xa, yv) \ - LE_OUT16((uint8_t *)(xa), yv); \ - LE_OUT16((uint8_t *)(xa) + 2, (yv) >> 16); - -#define LE_OUT64(xa, yv) \ - LE_OUT32((uint8_t *)(xa), yv); \ - LE_OUT32((uint8_t *)(xa) + 4, (yv) >> 32); - -#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_BYTEORDER_H */ diff --git a/zfs/lib/libsolcompat/include/sys/callb.h b/zfs/lib/libsolcompat/include/sys/callb.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/cmn_err.h b/zfs/lib/libsolcompat/include/sys/cmn_err.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/cred.h b/zfs/lib/libsolcompat/include/sys/cred.h deleted file mode 100644 index b4fb6381e..000000000 --- a/zfs/lib/libsolcompat/include/sys/cred.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_CRED_H -#define _SOL_SYS_CRED_H - -typedef struct cred cred_t; - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/dkio.h b/zfs/lib/libsolcompat/include/sys/dkio.h deleted file mode 100644 index 32f786565..000000000 --- a/zfs/lib/libsolcompat/include/sys/dkio.h +++ /dev/null @@ -1,484 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DKIO_H -#define _SYS_DKIO_H - - - -#include /* Needed for NDKMAP define */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Structures and definitions for disk io control commands - */ - -/* - * Structures used as data by ioctl calls. - */ - -#define DK_DEVLEN 16 /* device name max length, including */ - /* unit # & NULL (ie - "xyc1") */ - -/* - * Used for controller info - */ -struct dk_cinfo { - char dki_cname[DK_DEVLEN]; /* controller name (no unit #) */ - ushort_t dki_ctype; /* controller type */ - ushort_t dki_flags; /* flags */ - ushort_t dki_cnum; /* controller number */ - uint_t dki_addr; /* controller address */ - uint_t dki_space; /* controller bus type */ - uint_t dki_prio; /* interrupt priority */ - uint_t dki_vec; /* interrupt vector */ - char dki_dname[DK_DEVLEN]; /* drive name (no unit #) */ - uint_t dki_unit; /* unit number */ - uint_t dki_slave; /* slave number */ - ushort_t dki_partition; /* partition number */ - ushort_t dki_maxtransfer; /* max. transfer size in DEV_BSIZE */ -}; - -/* - * Controller types - */ -#define DKC_UNKNOWN 0 -#define DKC_CDROM 1 /* CD-ROM, SCSI or otherwise */ -#define DKC_WDC2880 2 -#define DKC_XXX_0 3 /* unassigned */ -#define DKC_XXX_1 4 /* unassigned */ -#define DKC_DSD5215 5 -#define DKC_ACB4000 7 -#define DKC_MD21 8 -#define DKC_XXX_2 9 /* unassigned */ -#define DKC_NCRFLOPPY 10 -#define DKC_SMSFLOPPY 12 -#define DKC_SCSI_CCS 13 /* SCSI CCS compatible */ -#define DKC_INTEL82072 14 /* native floppy chip */ -#define DKC_MD 16 /* meta-disk (virtual-disk) driver */ -#define DKC_INTEL82077 19 /* 82077 floppy disk controller */ -#define DKC_DIRECT 20 /* Intel direct attached device i.e. IDE */ -#define DKC_PCMCIA_MEM 21 /* PCMCIA memory disk-like type */ -#define DKC_PCMCIA_ATA 22 /* PCMCIA AT Attached type */ -#define DKC_VBD 23 /* virtual block device */ - -/* - * Sun reserves up through 1023 - */ - -#define DKC_CUSTOMER_BASE 1024 - -/* - * Flags - */ -#define DKI_BAD144 0x01 /* use DEC std 144 bad sector fwding */ -#define DKI_MAPTRK 0x02 /* controller does track mapping */ -#define DKI_FMTTRK 0x04 /* formats only full track at a time */ -#define DKI_FMTVOL 0x08 /* formats only full volume at a time */ -#define DKI_FMTCYL 0x10 /* formats only full cylinders at a time */ -#define DKI_HEXUNIT 0x20 /* unit number is printed as 3 hex digits */ -#define DKI_PCMCIA_PFD 0x40 /* PCMCIA pseudo-floppy memory card */ - -/* - * Used for all partitions - */ -struct dk_allmap { - struct dk_map dka_map[NDKMAP]; -}; - -#if defined(_SYSCALL32) -struct dk_allmap32 { - struct dk_map32 dka_map[NDKMAP]; -}; -#endif /* _SYSCALL32 */ - -/* - * Definition of a disk's geometry - */ -struct dk_geom { - unsigned short dkg_ncyl; /* # of data cylinders */ - unsigned short dkg_acyl; /* # of alternate cylinders */ - unsigned short dkg_bcyl; /* cyl offset (for fixed head area) */ - unsigned short dkg_nhead; /* # of heads */ - unsigned short dkg_obs1; /* obsolete */ - unsigned short dkg_nsect; /* # of data sectors per track */ - unsigned short dkg_intrlv; /* interleave factor */ - unsigned short dkg_obs2; /* obsolete */ - unsigned short dkg_obs3; /* obsolete */ - unsigned short dkg_apc; /* alternates per cyl (SCSI only) */ - unsigned short dkg_rpm; /* revolutions per minute */ - unsigned short dkg_pcyl; /* # of physical cylinders */ - unsigned short dkg_write_reinstruct; /* # sectors to skip, writes */ - unsigned short dkg_read_reinstruct; /* # sectors to skip, reads */ - unsigned short dkg_extra[7]; /* for compatible expansion */ -}; - -/* - * These defines are for historic compatibility with old drivers. - */ -#define dkg_bhead dkg_obs1 /* used to be head offset */ -#define dkg_gap1 dkg_obs2 /* used to be gap1 */ -#define dkg_gap2 dkg_obs3 /* used to be gap2 */ - -/* - * Disk io control commands - * Warning: some other ioctls with the DIOC prefix exist elsewhere. - * The Generic DKIOC numbers are from 0 - 50. - * The Floppy Driver uses 51 - 100. - * The Hard Disk (except SCSI) 101 - 106. (these are obsolete) - * The CDROM Driver 151 - 200. - * The USCSI ioctl 201 - 250. - */ -#define DKIOC (0x04 << 8) - -/* - * The following ioctls are generic in nature and need to be - * suported as appropriate by all disk drivers - */ -#define DKIOCGGEOM (DKIOC|1) /* Get geometry */ -#define DKIOCINFO (DKIOC|3) /* Get info */ -#define DKIOCEJECT (DKIOC|6) /* Generic 'eject' */ -#define DKIOCGVTOC (DKIOC|11) /* Get VTOC */ -#define DKIOCSVTOC (DKIOC|12) /* Set VTOC & Write to Disk */ - -/* - * Disk Cache Controls. These ioctls should be supported by - * all disk drivers. - * - * DKIOCFLUSHWRITECACHE when used from user-mode ignores the ioctl - * argument, but it should be passed as NULL to allow for future - * reinterpretation. From user-mode, this ioctl request is synchronous. - * - * When invoked from within the kernel, the arg can be NULL to indicate - * a synchronous request or can be the address of a struct dk_callback - * to request an asynchronous callback when the flush request is complete. - * In this case, the flag to the ioctl must include FKIOCTL and the - * dkc_callback field of the pointed to struct must be non-null or the - * request is made synchronously. - * - * In the callback case: if the ioctl returns 0, a callback WILL be performed. - * If the ioctl returns non-zero, a callback will NOT be performed. - * NOTE: In some cases, the callback may be done BEFORE the ioctl call - * returns. The caller's locking strategy should be prepared for this case. - */ -#define DKIOCFLUSHWRITECACHE (DKIOC|34) /* flush cache to phys medium */ - -struct dk_callback { - void (*dkc_callback)(void *dkc_cookie, int error); - void *dkc_cookie; - int dkc_flag; -}; - -/* bit flag definitions for dkc_flag */ -#define FLUSH_VOLATILE 0x1 /* Bit 0: if set, only flush */ - /* volatile cache; otherwise, flush */ - /* volatile and non-volatile cache */ - -#define DKIOCGETWCE (DKIOC|36) /* Get current write cache */ - /* enablement status */ -#define DKIOCSETWCE (DKIOC|37) /* Enable/Disable write cache */ - -/* - * The following ioctls are used by Sun drivers to communicate - * with their associated format routines. Support of these ioctls - * is not required of foreign drivers - */ -#define DKIOCSGEOM (DKIOC|2) /* Set geometry */ -#define DKIOCSAPART (DKIOC|4) /* Set all partitions */ -#define DKIOCGAPART (DKIOC|5) /* Get all partitions */ -#define DKIOCG_PHYGEOM (DKIOC|32) /* get physical geometry */ -#define DKIOCG_VIRTGEOM (DKIOC|33) /* get virtual geometry */ - -/* - * The following ioctl's are removable media support - */ -#define DKIOCLOCK (DKIOC|7) /* Generic 'lock' */ -#define DKIOCUNLOCK (DKIOC|8) /* Generic 'unlock' */ -#define DKIOCSTATE (DKIOC|13) /* Inquire insert/eject state */ -#define DKIOCREMOVABLE (DKIOC|16) /* is media removable */ - - -/* - * ioctl for hotpluggable devices - */ -#define DKIOCHOTPLUGGABLE (DKIOC|35) /* is hotpluggable */ - -/* - * Ioctl to force driver to re-read the alternate partition and rebuild - * the internal defect map. - */ -#define DKIOCADDBAD (DKIOC|20) /* Re-read the alternate map (IDE) */ -#define DKIOCGETDEF (DKIOC|21) /* read defect list (IDE) */ - -/* - * Used by applications to get disk defect information from IDE - * drives. - */ -#ifdef _SYSCALL32 -struct defect_header32 { - int head; - caddr32_t buffer; -}; -#endif /* _SYSCALL32 */ - -struct defect_header { - int head; - caddr_t buffer; -}; - -#define DKIOCPARTINFO (DKIOC|22) /* Get partition or slice parameters */ - -/* - * Used by applications to get partition or slice information - */ -#ifdef _SYSCALL32 -struct part_info32 { - daddr32_t p_start; - int p_length; -}; -#endif /* _SYSCALL32 */ - -struct part_info { - daddr_t p_start; - int p_length; -}; - -/* The following ioctls are for Optical Memory Device */ -#define DKIOC_EBP_ENABLE (DKIOC|40) /* enable by pass erase on write */ -#define DKIOC_EBP_DISABLE (DKIOC|41) /* disable by pass erase on write */ - -/* - * This state enum is the argument passed to the DKIOCSTATE ioctl. - */ -enum dkio_state { DKIO_NONE, DKIO_EJECTED, DKIO_INSERTED, DKIO_DEV_GONE }; - -#define DKIOCGMEDIAINFO (DKIOC|42) /* get information about the media */ - -/* - * ioctls to read/write mboot info. - */ -#define DKIOCGMBOOT (DKIOC|43) /* get mboot info */ -#define DKIOCSMBOOT (DKIOC|44) /* set mboot info */ - -/* - * ioctl to get the device temperature. - */ -#define DKIOCGTEMPERATURE (DKIOC|45) /* get temperature */ - -/* - * Used for providing the temperature. - */ - -struct dk_temperature { - uint_t dkt_flags; /* Flags */ - short dkt_cur_temp; /* Current disk temperature */ - short dkt_ref_temp; /* reference disk temperature */ -}; - -#define DKT_BYPASS_PM 0x1 -#define DKT_INVALID_TEMP 0xFFFF - - -/* - * Used for Media info or the current profile info - */ -struct dk_minfo { - uint_t dki_media_type; /* Media type or profile info */ - uint_t dki_lbsize; /* Logical blocksize of media */ - diskaddr_t dki_capacity; /* Capacity as # of dki_lbsize blks */ -}; - -/* - * Media types or profiles known - */ -#define DK_UNKNOWN 0x00 /* Media inserted - type unknown */ - - -/* - * SFF 8090 Specification Version 3, media types 0x01 - 0xfffe are retained to - * maintain compatibility with SFF8090. The following define the - * optical media type. - */ -#define DK_REMOVABLE_DISK 0x02 /* Removable Disk */ -#define DK_MO_ERASABLE 0x03 /* MO Erasable */ -#define DK_MO_WRITEONCE 0x04 /* MO Write once */ -#define DK_AS_MO 0x05 /* AS MO */ -#define DK_CDROM 0x08 /* CDROM */ -#define DK_CDR 0x09 /* CD-R */ -#define DK_CDRW 0x0A /* CD-RW */ -#define DK_DVDROM 0x10 /* DVD-ROM */ -#define DK_DVDR 0x11 /* DVD-R */ -#define DK_DVDRAM 0x12 /* DVD_RAM or DVD-RW */ - -/* - * Media types for other rewritable magnetic media - */ -#define DK_FIXED_DISK 0x10001 /* Fixed disk SCSI or otherwise */ -#define DK_FLOPPY 0x10002 /* Floppy media */ -#define DK_ZIP 0x10003 /* IOMEGA ZIP media */ -#define DK_JAZ 0x10004 /* IOMEGA JAZ media */ - -#define DKIOCSETEFI (DKIOC|17) /* Set EFI info */ -#define DKIOCGETEFI (DKIOC|18) /* Get EFI info */ - -#define DKIOCPARTITION (DKIOC|9) /* Get partition info */ - -/* - * Ioctls to get/set volume capabilities related to Logical Volume Managers. - * They include the ability to get/set capabilities and to issue a read to a - * specific underlying device of a replicated device. - */ - -#define DKIOCGETVOLCAP (DKIOC | 25) /* Get volume capabilities */ -#define DKIOCSETVOLCAP (DKIOC | 26) /* Set volume capabilities */ -#define DKIOCDMR (DKIOC | 27) /* Issue a directed read */ - -typedef uint_t volcapinfo_t; - -typedef uint_t volcapset_t; - -#define DKV_ABR_CAP 0x00000001 /* Support Appl.Based Recovery */ -#define DKV_DMR_CAP 0x00000002 /* Support Directed Mirror Read */ - -typedef struct volcap { - volcapinfo_t vc_info; /* Capabilities available */ - volcapset_t vc_set; /* Capabilities set */ -} volcap_t; - -#define VOL_SIDENAME 256 - -typedef struct vol_directed_rd { - int vdr_flags; - offset_t vdr_offset; - size_t vdr_nbytes; - size_t vdr_bytesread; - void *vdr_data; - int vdr_side; - char vdr_side_name[VOL_SIDENAME]; -} vol_directed_rd_t; - -#define DKV_SIDE_INIT (-1) -#define DKV_DMR_NEXT_SIDE 0x00000001 -#define DKV_DMR_DONE 0x00000002 -#define DKV_DMR_ERROR 0x00000004 -#define DKV_DMR_SUCCESS 0x00000008 -#define DKV_DMR_SHORT 0x00000010 - -#ifdef _MULTI_DATAMODEL -#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 -#pragma pack(4) -#endif -typedef struct vol_directed_rd32 { - int32_t vdr_flags; - offset_t vdr_offset; /* 64-bit element on 32-bit alignment */ - size32_t vdr_nbytes; - size32_t vdr_bytesread; - caddr32_t vdr_data; - int32_t vdr_side; - char vdr_side_name[VOL_SIDENAME]; -} vol_directed_rd32_t; -#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 -#pragma pack() -#endif -#endif /* _MULTI_DATAMODEL */ - -/* - * The ioctl is used to fetch disk's device type, vendor ID, - * model number/product ID, firmware revision and serial number together. - * - * Currently there are two device types - DKD_ATA_TYPE which means the - * disk is driven by cmdk/ata or dad/uata driver, and DKD_SCSI_TYPE - * which means the disk is driven by sd/scsi hba driver. - */ -#define DKIOC_GETDISKID (DKIOC|46) - -/* These two labels are for dkd_dtype of dk_disk_id_t */ -#define DKD_ATA_TYPE 0x01 /* ATA disk or legacy mode SATA disk */ -#define DKD_SCSI_TYPE 0x02 /* SCSI disk or native mode SATA disk */ - -#define DKD_ATA_MODEL 40 /* model number length */ -#define DKD_ATA_FWVER 8 /* firmware revision length */ -#define DKD_ATA_SERIAL 20 /* serial number length */ - -#define DKD_SCSI_VENDOR 8 /* vendor ID length */ -#define DKD_SCSI_PRODUCT 16 /* product ID length */ -#define DKD_SCSI_REVLEVEL 4 /* revision level length */ -#define DKD_SCSI_SERIAL 12 /* serial number length */ - -/* - * The argument type for DKIOC_GETDISKID ioctl. - */ -typedef struct dk_disk_id { - uint_t dkd_dtype; - union { - struct { - char dkd_amodel[DKD_ATA_MODEL]; /* 40 bytes */ - char dkd_afwver[DKD_ATA_FWVER]; /* 8 bytes */ - char dkd_aserial[DKD_ATA_SERIAL]; /* 20 bytes */ - } ata_disk_id; - struct { - char dkd_svendor[DKD_SCSI_VENDOR]; /* 8 bytes */ - char dkd_sproduct[DKD_SCSI_PRODUCT]; /* 16 bytes */ - char dkd_sfwver[DKD_SCSI_REVLEVEL]; /* 4 bytes */ - char dkd_sserial[DKD_SCSI_SERIAL]; /* 12 bytes */ - } scsi_disk_id; - } disk_id; -} dk_disk_id_t; - -/* - * The ioctl is used to update the firmware of device. - */ -#define DKIOC_UPDATEFW (DKIOC|47) - -/* The argument type for DKIOC_UPDATEFW ioctl */ -typedef struct dk_updatefw { - caddr_t dku_ptrbuf; /* pointer to firmware buf */ - uint_t dku_size; /* firmware buf length */ - uint8_t dku_type; /* firmware update type */ -} dk_updatefw_t; - -#ifdef _SYSCALL32 -typedef struct dk_updatefw_32 { - caddr32_t dku_ptrbuf; /* pointer to firmware buf */ - uint_t dku_size; /* firmware buf length */ - uint8_t dku_type; /* firmware update type */ -} dk_updatefw_32_t; -#endif /* _SYSCALL32 */ - -/* - * firmware update type - temporary or permanent use - */ -#define FW_TYPE_TEMP 0x0 /* temporary use */ -#define FW_TYPE_PERM 0x1 /* permanent use */ - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_DKIO_H */ diff --git a/zfs/lib/libsolcompat/include/sys/dklabel.h b/zfs/lib/libsolcompat/include/sys/dklabel.h deleted file mode 100644 index 77d5da10e..000000000 --- a/zfs/lib/libsolcompat/include/sys/dklabel.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1990-2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DKLABEL_H -#define _SYS_DKLABEL_H - - - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Miscellaneous defines - */ -#define DKL_MAGIC 0xDABE /* magic number */ -#define FKL_MAGIC 0xff /* magic number for DOS floppies */ - -#if defined(_SUNOS_VTOC_16) -#define NDKMAP 16 /* # of logical partitions */ -#define DK_LABEL_LOC 1 /* location of disk label */ -#elif defined(_SUNOS_VTOC_8) -#define NDKMAP 8 /* # of logical partitions */ -#define DK_LABEL_LOC 0 /* location of disk label */ -#else -#error "No VTOC format defined." -#endif - -#define LEN_DKL_ASCII 128 /* length of dkl_asciilabel */ -#define LEN_DKL_VVOL 8 /* length of v_volume */ -#define DK_LABEL_SIZE 512 /* size of disk label */ -#define DK_MAX_BLOCKS 0x7fffffff /* max # of blocks handled */ - -/* - * Reserve two cylinders on SCSI disks. - * One is for the backup disk label and the other is for the deviceid. - * - * IPI disks only reserve one cylinder, but they will go away soon. - * CDROMs do not reserve any cylinders. - */ -#define DK_ACYL 2 - -/* - * Format of a Sun disk label. - * Resides in cylinder 0, head 0, sector 0. - * - * sizeof (struct dk_label) should be 512 (the current sector size), - * but should the sector size increase, this structure should remain - * at the beginning of the sector. - */ - -/* - * partition headers: section 1 - * Returned in struct dk_allmap by ioctl DKIOC[SG]APART (dkio(7I)) - */ -struct dk_map { - daddr_t dkl_cylno; /* starting cylinder */ - daddr_t dkl_nblk; /* number of blocks; if == 0, */ - /* partition is undefined */ -}; - -/* - * partition headers: section 1 - * Fixed size for on-disk dk_label - */ -struct dk_map32 { - daddr32_t dkl_cylno; /* starting cylinder */ - daddr32_t dkl_nblk; /* number of blocks; if == 0, */ - /* partition is undefined */ -}; - -/* - * partition headers: section 2, - * brought over from AT&T SVr4 vtoc structure. - */ -struct dk_map2 { - uint16_t p_tag; /* ID tag of partition */ - uint16_t p_flag; /* permission flag */ -}; - -struct dkl_partition { - uint16_t p_tag; /* ID tag of partition */ - uint16_t p_flag; /* permision flags */ - daddr32_t p_start; /* start sector no of partition */ - int32_t p_size; /* # of blocks in partition */ -}; - - -/* - * VTOC inclusions from AT&T SVr4 - * Fixed sized types for on-disk VTOC - */ - -struct dk_vtoc { -#if defined(_SUNOS_VTOC_16) - uint32_t v_bootinfo[3]; /* info for mboot (unsupported) */ - uint32_t v_sanity; /* to verify vtoc sanity */ - uint32_t v_version; /* layout version */ - char v_volume[LEN_DKL_VVOL]; /* volume name */ - uint16_t v_sectorsz; /* sector size in bytes */ - uint16_t v_nparts; /* number of partitions */ - uint32_t v_reserved[10]; /* free space */ - struct dkl_partition v_part[NDKMAP]; /* partition headers */ - time32_t timestamp[NDKMAP]; /* partition timestamp (unsupported) */ - char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ -#elif defined(_SUNOS_VTOC_8) - uint32_t v_version; /* layout version */ - char v_volume[LEN_DKL_VVOL]; /* volume name */ - uint16_t v_nparts; /* number of partitions */ - struct dk_map2 v_part[NDKMAP]; /* partition hdrs, sec 2 */ - uint32_t v_bootinfo[3]; /* info needed by mboot */ - uint32_t v_sanity; /* to verify vtoc sanity */ - uint32_t v_reserved[10]; /* free space */ - time32_t v_timestamp[NDKMAP]; /* partition timestamp */ -#else -#error "No VTOC format defined." -#endif -}; - -/* - * define the amount of disk label padding needed to make - * the entire structure occupy 512 bytes. - */ -#if defined(_SUNOS_VTOC_16) -#define LEN_DKL_PAD (DK_LABEL_SIZE - \ - ((sizeof (struct dk_vtoc) + \ - (4 * sizeof (uint32_t)) + \ - (12 * sizeof (uint16_t)) + \ - (2 * (sizeof (uint16_t)))))) -#elif defined(_SUNOS_VTOC_8) -#define LEN_DKL_PAD (DK_LABEL_SIZE \ - - ((LEN_DKL_ASCII) + \ - (sizeof (struct dk_vtoc)) + \ - (sizeof (struct dk_map32) * NDKMAP) + \ - (14 * (sizeof (uint16_t))) + \ - (2 * (sizeof (uint16_t))))) -#else -#error "No VTOC format defined." -#endif - - -struct dk_label { -#if defined(_SUNOS_VTOC_16) - struct dk_vtoc dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ - uint32_t dkl_pcyl; /* # of physical cylinders */ - uint32_t dkl_ncyl; /* # of data cylinders */ - uint16_t dkl_acyl; /* # of alternate cylinders */ - uint16_t dkl_bcyl; /* cyl offset (for fixed head area) */ - uint32_t dkl_nhead; /* # of heads */ - uint32_t dkl_nsect; /* # of data sectors per track */ - uint16_t dkl_intrlv; /* interleave factor */ - uint16_t dkl_skew; /* skew factor */ - uint16_t dkl_apc; /* alternates per cyl (SCSI only) */ - uint16_t dkl_rpm; /* revolutions per minute */ - uint16_t dkl_write_reinstruct; /* # sectors to skip, writes */ - uint16_t dkl_read_reinstruct; /* # sectors to skip, reads */ - uint16_t dkl_extra[4]; /* for compatible expansion */ - char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */ -#elif defined(_SUNOS_VTOC_8) - char dkl_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ - struct dk_vtoc dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ - uint16_t dkl_write_reinstruct; /* # sectors to skip, writes */ - uint16_t dkl_read_reinstruct; /* # sectors to skip, reads */ - char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */ - uint16_t dkl_rpm; /* rotations per minute */ - uint16_t dkl_pcyl; /* # physical cylinders */ - uint16_t dkl_apc; /* alternates per cylinder */ - uint16_t dkl_obs1; /* obsolete */ - uint16_t dkl_obs2; /* obsolete */ - uint16_t dkl_intrlv; /* interleave factor */ - uint16_t dkl_ncyl; /* # of data cylinders */ - uint16_t dkl_acyl; /* # of alternate cylinders */ - uint16_t dkl_nhead; /* # of heads in this partition */ - uint16_t dkl_nsect; /* # of 512 byte sectors per track */ - uint16_t dkl_obs3; /* obsolete */ - uint16_t dkl_obs4; /* obsolete */ - struct dk_map32 dkl_map[NDKMAP]; /* logical partition headers */ -#else -#error "No VTOC format defined." -#endif - uint16_t dkl_magic; /* identifies this label format */ - uint16_t dkl_cksum; /* xor checksum of sector */ -}; - -#if defined(_SUNOS_VTOC_16) -#define dkl_asciilabel dkl_vtoc.v_asciilabel -#define v_timestamp timestamp - -#elif defined(_SUNOS_VTOC_8) - -/* - * These defines are for historic compatibility with old drivers. - */ -#define dkl_gap1 dkl_obs1 /* used to be gap1 */ -#define dkl_gap2 dkl_obs2 /* used to be gap2 */ -#define dkl_bhead dkl_obs3 /* used to be label head offset */ -#define dkl_ppart dkl_obs4 /* used to by physical partition */ -#else -#error "No VTOC format defined." -#endif - -struct fk_label { /* DOS floppy label */ - uchar_t fkl_type; - uchar_t fkl_magich; - uchar_t fkl_magicl; - uchar_t filler; -}; - -/* - * Layout of stored fabricated device id (on-disk) - */ -#define DK_DEVID_BLKSIZE (512) -#define DK_DEVID_SIZE (DK_DEVID_BLKSIZE - ((sizeof (uchar_t) * 7))) -#define DK_DEVID_REV_MSB (0) -#define DK_DEVID_REV_LSB (1) - -struct dk_devid { - uchar_t dkd_rev_hi; /* revision (MSB) */ - uchar_t dkd_rev_lo; /* revision (LSB) */ - uchar_t dkd_flags; /* flags (not used yet) */ - uchar_t dkd_devid[DK_DEVID_SIZE]; /* devid stored here */ - uchar_t dkd_checksum3; /* checksum (MSB) */ - uchar_t dkd_checksum2; - uchar_t dkd_checksum1; - uchar_t dkd_checksum0; /* checksum (LSB) */ -}; - -#define DKD_GETCHKSUM(dkd) ((dkd)->dkd_checksum3 << 24) + \ - ((dkd)->dkd_checksum2 << 16) + \ - ((dkd)->dkd_checksum1 << 8) + \ - ((dkd)->dkd_checksum0) - -#define DKD_FORMCHKSUM(c, dkd) (dkd)->dkd_checksum3 = hibyte(hiword((c))); \ - (dkd)->dkd_checksum2 = lobyte(hiword((c))); \ - (dkd)->dkd_checksum1 = hibyte(loword((c))); \ - (dkd)->dkd_checksum0 = lobyte(loword((c))); -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_DKLABEL_H */ diff --git a/zfs/lib/libsolcompat/include/sys/feature_tests.h b/zfs/lib/libsolcompat/include/sys/feature_tests.h deleted file mode 100644 index 96f627172..000000000 --- a/zfs/lib/libsolcompat/include/sys/feature_tests.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_FEATURE_TESTS_H -#define _SYS_FEATURE_TESTS_H - -#define __NORETURN __attribute__((__noreturn__)) - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/file.h b/zfs/lib/libsolcompat/include/sys/file.h deleted file mode 100644 index 8908390b8..000000000 --- a/zfs/lib/libsolcompat/include/sys/file.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_FILE_H -#define _SOL_SYS_FILE_H - -#include_next - -#include - -#define FREAD 1 -#define FWRITE 2 -//#define FAPPEND 8 - -#define FCREAT O_CREAT -#define FTRUNC O_TRUNC -#define FOFFMAX O_LARGEFILE -#define FSYNC O_SYNC -#define FDSYNC O_DSYNC -#define FRSYNC O_RSYNC -#define FEXCL O_EXCL - -#define FNODSYNC 0x10000 /* fsync pseudo flag */ -#define FNOFOLLOW 0x20000 /* don't follow symlinks */ -#define FIGNORECASE 0x80000 /* request case-insensitive lookups */ - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/fm/protocol.h b/zfs/lib/libsolcompat/include/sys/fm/protocol.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/fm/util.h b/zfs/lib/libsolcompat/include/sys/fm/util.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/idmap.h b/zfs/lib/libsolcompat/include/sys/idmap.h deleted file mode 100644 index 156afbfab..000000000 --- a/zfs/lib/libsolcompat/include/sys/idmap.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_IDMAP_H -#define _SYS_IDMAP_H - - - -/* Idmap status codes */ -#define IDMAP_SUCCESS 0 -#define IDMAP_NEXT 1 -#define IDMAP_ERR_OTHER -10000 -#define IDMAP_ERR_INTERNAL -9999 -#define IDMAP_ERR_MEMORY -9998 -#define IDMAP_ERR_NORESULT -9997 -#define IDMAP_ERR_NOTUSER -9996 -#define IDMAP_ERR_NOTGROUP -9995 -#define IDMAP_ERR_NOTSUPPORTED -9994 -#define IDMAP_ERR_W2U_NAMERULE -9993 -#define IDMAP_ERR_U2W_NAMERULE -9992 -#define IDMAP_ERR_CACHE -9991 -#define IDMAP_ERR_DB -9990 -#define IDMAP_ERR_ARG -9989 -#define IDMAP_ERR_SID -9988 -#define IDMAP_ERR_IDTYPE -9987 -#define IDMAP_ERR_RPC_HANDLE -9986 -#define IDMAP_ERR_RPC -9985 -#define IDMAP_ERR_CLIENT_HANDLE -9984 -#define IDMAP_ERR_BUSY -9983 -#define IDMAP_ERR_PERMISSION_DENIED -9982 -#define IDMAP_ERR_NOMAPPING -9981 -#define IDMAP_ERR_NEW_ID_ALLOC_REQD -9980 -#define IDMAP_ERR_DOMAIN -9979 -#define IDMAP_ERR_SECURITY -9978 -#define IDMAP_ERR_NOTFOUND -9977 -#define IDMAP_ERR_DOMAIN_NOTFOUND -9976 -#define IDMAP_ERR_UPDATE_NOTALLOWED -9975 -#define IDMAP_ERR_CFG -9974 -#define IDMAP_ERR_CFG_CHANGE -9973 -#define IDMAP_ERR_NOTMAPPED_WELLKNOWN -9972 -#define IDMAP_ERR_RETRIABLE_NET_ERR -9971 -#define IDMAP_ERR_W2U_NAMERULE_CONFLICT -9970 -#define IDMAP_ERR_U2W_NAMERULE_CONFLICT -9969 -#define IDMAP_ERR_BAD_UTF8 -9968 - -/* Reserved GIDs for some well-known SIDs */ -#define IDMAP_WK_LOCAL_SYSTEM_GID 2147483648U -#define IDMAP_WK_CREATOR_GROUP_GID 2147483649U -#define IDMAP_WK__MAX_GID 2147483649U - -/* Reserved UIDs for some well-known SIDs */ -#define IDMAP_WK_CREATOR_OWNER_UID 2147483648U -#define IDMAP_WK__MAX_UID 2147483648U - -/* Reserved SIDs */ -#define IDMAP_WK_CREATOR_SID_AUTHORITY "S-1-3" - -/* - * Max door RPC size for ID mapping (can't be too large relative to the - * default user-land thread stack size, since clnt_door_call() - * alloca()s). See libidmap:idmap_init(). - */ -#define IDMAP_MAX_DOOR_RPC (256 * 1024) - -#endif /* _SYS_IDMAP_H */ diff --git a/zfs/lib/libsolcompat/include/sys/int_limits.h b/zfs/lib/libsolcompat/include/sys/int_limits.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/int_types.h b/zfs/lib/libsolcompat/include/sys/int_types.h deleted file mode 100644 index 8049f02f1..000000000 --- a/zfs/lib/libsolcompat/include/sys/int_types.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/zfs/lib/libsolcompat/include/sys/inttypes.h b/zfs/lib/libsolcompat/include/sys/inttypes.h deleted file mode 100644 index 7630f2d4c..000000000 --- a/zfs/lib/libsolcompat/include/sys/inttypes.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_INTTYPES_H -#define _SOL_SYS_INTTYPES_H - -#include - -#define _INT64_TYPE - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/isa_defs.h b/zfs/lib/libsolcompat/include/sys/isa_defs.h deleted file mode 100644 index cd2840d0e..000000000 --- a/zfs/lib/libsolcompat/include/sys/isa_defs.h +++ /dev/null @@ -1,482 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ISA_DEFS_H -#define _SYS_ISA_DEFS_H - - - -/* - * This header file serves to group a set of well known defines and to - * set these for each instruction set architecture. These defines may - * be divided into two groups; characteristics of the processor and - * implementation choices for Solaris on a processor. - * - * Processor Characteristics: - * - * _LITTLE_ENDIAN / _BIG_ENDIAN: - * The natural byte order of the processor. A pointer to an int points - * to the least/most significant byte of that int. - * - * _STACK_GROWS_UPWARD / _STACK_GROWS_DOWNWARD: - * The processor specific direction of stack growth. A push onto the - * stack increases/decreases the stack pointer, so it stores data at - * successively higher/lower addresses. (Stackless machines ignored - * without regrets). - * - * _LONG_LONG_HTOL / _LONG_LONG_LTOH: - * A pointer to a long long points to the most/least significant long - * within that long long. - * - * _BIT_FIELDS_HTOL / _BIT_FIELDS_LTOH: - * The C compiler assigns bit fields from the high/low to the low/high end - * of an int (most to least significant vs. least to most significant). - * - * _IEEE_754: - * The processor (or supported implementations of the processor) - * supports the ieee-754 floating point standard. No other floating - * point standards are supported (or significant). Any other supported - * floating point formats are expected to be cased on the ISA processor - * symbol. - * - * _CHAR_IS_UNSIGNED / _CHAR_IS_SIGNED: - * The C Compiler implements objects of type `char' as `unsigned' or - * `signed' respectively. This is really an implementation choice of - * the compiler writer, but it is specified in the ABI and tends to - * be uniform across compilers for an instruction set architecture. - * Hence, it has the properties of a processor characteristic. - * - * _CHAR_ALIGNMENT / _SHORT_ALIGNMENT / _INT_ALIGNMENT / _LONG_ALIGNMENT / - * _LONG_LONG_ALIGNMENT / _DOUBLE_ALIGNMENT / _LONG_DOUBLE_ALIGNMENT / - * _POINTER_ALIGNMENT / _FLOAT_ALIGNMENT: - * The ABI defines alignment requirements of each of the primitive - * object types. Some, if not all, may be hardware requirements as - * well. The values are expressed in "byte-alignment" units. - * - * _MAX_ALIGNMENT: - * The most stringent alignment requirement as specified by the ABI. - * Equal to the maximum of all the above _XXX_ALIGNMENT values. - * - * _ALIGNMENT_REQUIRED: - * True or false (1 or 0) whether or not the hardware requires the ABI - * alignment. - * - * _LONG_LONG_ALIGNMENT_32 - * The 32-bit ABI supported by a 64-bit kernel may have different - * alignment requirements for primitive object types. The value of this - * identifier is expressed in "byte-alignment" units. - * - * _HAVE_CPUID_INSN - * This indicates that the architecture supports the 'cpuid' - * instruction as defined by Intel. (Intel allows other vendors - * to extend the instruction for their own purposes.) - * - * - * Implementation Choices: - * - * _ILP32 / _LP64: - * This specifies the compiler data type implementation as specified in - * the relevant ABI. The choice between these is strongly influenced - * by the underlying hardware, but is not absolutely tied to it. - * Currently only two data type models are supported: - * - * _ILP32: - * Int/Long/Pointer are 32 bits. This is the historical UNIX - * and Solaris implementation. Due to its historical standing, - * this is the default case. - * - * _LP64: - * Long/Pointer are 64 bits, Int is 32 bits. This is the chosen - * implementation for 64-bit ABIs such as SPARC V9. - * - * _I32LPx: - * A compilation environment where 'int' is 32-bit, and - * longs and pointers are simply the same size. - * - * In all cases, Char is 8 bits and Short is 16 bits. - * - * _SUNOS_VTOC_8 / _SUNOS_VTOC_16 / _SVR4_VTOC_16: - * This specifies the form of the disk VTOC (or label): - * - * _SUNOS_VTOC_8: - * This is a VTOC form which is upwardly compatible with the - * SunOS 4.x disk label and allows 8 partitions per disk. - * - * _SUNOS_VTOC_16: - * In this format the incore vtoc image matches the ondisk - * version. It allows 16 slices per disk, and is not - * compatible with the SunOS 4.x disk label. - * - * Note that these are not the only two VTOC forms possible and - * additional forms may be added. One possible form would be the - * SVr4 VTOC form. The symbol for that is reserved now, although - * it is not implemented. - * - * _SVR4_VTOC_16: - * This VTOC form is compatible with the System V Release 4 - * VTOC (as implemented on the SVr4 Intel and 3b ports) with - * 16 partitions per disk. - * - * - * _DMA_USES_PHYSADDR / _DMA_USES_VIRTADDR - * This describes the type of addresses used by system DMA: - * - * _DMA_USES_PHYSADDR: - * This type of DMA, used in the x86 implementation, - * requires physical addresses for DMA buffers. The 24-bit - * addresses used by some legacy boards is the source of the - * "low-memory" (<16MB) requirement for some devices using DMA. - * - * _DMA_USES_VIRTADDR: - * This method of DMA allows the use of virtual addresses for - * DMA transfers. - * - * _FIRMWARE_NEEDS_FDISK / _NO_FDISK_PRESENT - * This indicates the presence/absence of an fdisk table. - * - * _FIRMWARE_NEEDS_FDISK - * The fdisk table is required by system firmware. If present, - * it allows a disk to be subdivided into multiple fdisk - * partitions, each of which is equivalent to a separate, - * virtual disk. This enables the co-existence of multiple - * operating systems on a shared hard disk. - * - * _NO_FDISK_PRESENT - * If the fdisk table is absent, it is assumed that the entire - * media is allocated for a single operating system. - * - * _HAVE_TEM_FIRMWARE - * Defined if this architecture has the (fallback) option of - * using prom_* calls for doing I/O if a suitable kernel driver - * is not available to do it. - * - * _DONT_USE_1275_GENERIC_NAMES - * Controls whether or not device tree node names should - * comply with the IEEE 1275 "Generic Names" Recommended - * Practice. With _DONT_USE_GENERIC_NAMES, device-specific - * names identifying the particular device will be used. - * - * __i386_COMPAT - * This indicates whether the i386 ABI is supported as a *non-native* - * mode for the platform. When this symbol is defined: - * - 32-bit xstat-style system calls are enabled - * - 32-bit xmknod-style system calls are enabled - * - 32-bit system calls use i386 sizes -and- alignments - * - * Note that this is NOT defined for the i386 native environment! - * - * __x86 - * This is ONLY a synonym for defined(__i386) || defined(__amd64) - * which is useful only insofar as these two architectures share - * common attributes. Analogous to __sparc. - * - * _PSM_MODULES - * This indicates whether or not the implementation uses PSM - * modules for processor support, reading /etc/mach from inside - * the kernel to extract a list. - * - * _RTC_CONFIG - * This indicates whether or not the implementation uses /etc/rtc_config - * to configure the real-time clock in the kernel. - * - * _UNIX_KRTLD - * This indicates that the implementation uses a dynamically - * linked unix + krtld to form the core kernel image at boot - * time, or (in the absence of this symbol) a prelinked kernel image. - * - * _OBP - * This indicates the firmware interface is OBP. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The following set of definitions characterize Solaris on AMD's - * 64-bit systems. - */ -#if defined(__x86_64) || defined(__amd64) - -#if !defined(__amd64) -#define __amd64 /* preferred guard */ -#endif - -#if !defined(__x86) -#define __x86 -#endif - -/* - * Define the appropriate "processor characteristics" - */ -#define _LITTLE_ENDIAN -#define _STACK_GROWS_DOWNWARD -#define _LONG_LONG_LTOH -#define _BIT_FIELDS_LTOH -#define _IEEE_754 -#define _CHAR_IS_SIGNED -#define _BOOL_ALIGNMENT 1 -#define _CHAR_ALIGNMENT 1 -#define _SHORT_ALIGNMENT 2 -#define _INT_ALIGNMENT 4 -#define _FLOAT_ALIGNMENT 4 -#define _FLOAT_COMPLEX_ALIGNMENT 4 -#define _LONG_ALIGNMENT 8 -#define _LONG_LONG_ALIGNMENT 8 -#define _DOUBLE_ALIGNMENT 8 -#define _DOUBLE_COMPLEX_ALIGNMENT 8 -#define _LONG_DOUBLE_ALIGNMENT 16 -#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 16 -#define _POINTER_ALIGNMENT 8 -#define _MAX_ALIGNMENT 16 -#define _ALIGNMENT_REQUIRED 1 - -/* - * Different alignment constraints for the i386 ABI in compatibility mode - */ -#define _LONG_LONG_ALIGNMENT_32 4 - -/* - * Define the appropriate "implementation choices". - */ -#if !defined(_LP64) -#define _LP64 -#endif -#if !defined(_I32LPx) && defined(_KERNEL) -#define _I32LPx -#endif -#define _MULTI_DATAMODEL -#define _SUNOS_VTOC_16 -#define _DMA_USES_PHYSADDR -#define _FIRMWARE_NEEDS_FDISK -#define __i386_COMPAT -#define _PSM_MODULES -#define _RTC_CONFIG -#define _DONT_USE_1275_GENERIC_NAMES -#define _HAVE_CPUID_INSN - -/* - * The feature test macro __i386 is generic for all processors implementing - * the Intel 386 instruction set or a superset of it. Specifically, this - * includes all members of the 386, 486, and Pentium family of processors. - */ -#elif defined(__i386) || defined(__i386__) - -#if !defined(__i386) -#define __i386 -#endif - -#if !defined(__x86) -#define __x86 -#endif - -/* - * Define the appropriate "processor characteristics" - */ -#define _LITTLE_ENDIAN -#define _STACK_GROWS_DOWNWARD -#define _LONG_LONG_LTOH -#define _BIT_FIELDS_LTOH -#define _IEEE_754 -#define _CHAR_IS_SIGNED -#define _BOOL_ALIGNMENT 1 -#define _CHAR_ALIGNMENT 1 -#define _SHORT_ALIGNMENT 2 -#define _INT_ALIGNMENT 4 -#define _FLOAT_ALIGNMENT 4 -#define _FLOAT_COMPLEX_ALIGNMENT 4 -#define _LONG_ALIGNMENT 4 -#define _LONG_LONG_ALIGNMENT 4 -#define _DOUBLE_ALIGNMENT 4 -#define _DOUBLE_COMPLEX_ALIGNMENT 4 -#define _LONG_DOUBLE_ALIGNMENT 4 -#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 4 -#define _POINTER_ALIGNMENT 4 -#define _MAX_ALIGNMENT 4 -#define _ALIGNMENT_REQUIRED 0 - -#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT - -/* - * Define the appropriate "implementation choices". - */ -#define _ILP32 -#if !defined(_I32LPx) && defined(_KERNEL) -#define _I32LPx -#endif -#define _SUNOS_VTOC_16 -#define _DMA_USES_PHYSADDR -#define _FIRMWARE_NEEDS_FDISK -#define _PSM_MODULES -#define _RTC_CONFIG -#define _DONT_USE_1275_GENERIC_NAMES -#define _HAVE_CPUID_INSN - -/* - * The following set of definitions characterize the Solaris on SPARC systems. - * - * The symbol __sparc indicates any of the SPARC family of processor - * architectures. This includes SPARC V7, SPARC V8 and SPARC V9. - * - * The symbol __sparcv8 indicates the 32-bit SPARC V8 architecture as defined - * by Version 8 of the SPARC Architecture Manual. (SPARC V7 is close enough - * to SPARC V8 for the former to be subsumed into the latter definition.) - * - * The symbol __sparcv9 indicates the 64-bit SPARC V9 architecture as defined - * by Version 9 of the SPARC Architecture Manual. - * - * The symbols __sparcv8 and __sparcv9 are mutually exclusive, and are only - * relevant when the symbol __sparc is defined. - */ -/* - * XXX Due to the existence of 5110166, "defined(__sparcv9)" needs to be added - * to support backwards builds. This workaround should be removed in s10_71. - */ -#elif defined(__sparc) || defined(__sparcv9) || defined(__sparc__) -#if !defined(__sparc) -#define __sparc -#endif - -/* - * You can be 32-bit or 64-bit, but not both at the same time. - */ -#if defined(__sparcv8) && defined(__sparcv9) -#error "SPARC Versions 8 and 9 are mutually exclusive choices" -#endif - -/* - * Existing compilers do not set __sparcv8. Years will transpire before - * the compilers can be depended on to set the feature test macro. In - * the interim, we'll set it here on the basis of historical behaviour; - * if you haven't asked for SPARC V9, then you must've meant SPARC V8. - */ -#if !defined(__sparcv9) && !defined(__sparcv8) -#define __sparcv8 -#endif - -/* - * Define the appropriate "processor characteristics" shared between - * all Solaris on SPARC systems. - */ -#define _BIG_ENDIAN -#define _STACK_GROWS_DOWNWARD -#define _LONG_LONG_HTOL -#define _BIT_FIELDS_HTOL -#define _IEEE_754 -#define _CHAR_IS_SIGNED -#define _BOOL_ALIGNMENT 1 -#define _CHAR_ALIGNMENT 1 -#define _SHORT_ALIGNMENT 2 -#define _INT_ALIGNMENT 4 -#define _FLOAT_ALIGNMENT 4 -#define _FLOAT_COMPLEX_ALIGNMENT 4 -#define _LONG_LONG_ALIGNMENT 8 -#define _DOUBLE_ALIGNMENT 8 -#define _DOUBLE_COMPLEX_ALIGNMENT 8 -#define _ALIGNMENT_REQUIRED 1 - -/* - * Define the appropriate "implementation choices" shared between versions. - */ -#define _SUNOS_VTOC_8 -#define _DMA_USES_VIRTADDR -#define _NO_FDISK_PRESENT -#define _HAVE_TEM_FIRMWARE -#define _OBP - -/* - * The following set of definitions characterize the implementation of - * 32-bit Solaris on SPARC V8 systems. - */ -#if defined(__sparcv8) - -/* - * Define the appropriate "processor characteristics" - */ -#define _LONG_ALIGNMENT 4 -#define _LONG_DOUBLE_ALIGNMENT 8 -#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 8 -#define _POINTER_ALIGNMENT 4 -#define _MAX_ALIGNMENT 8 - -#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT - -/* - * Define the appropriate "implementation choices" - */ -#define _ILP32 -#if !defined(_I32LPx) && defined(_KERNEL) -#define _I32LPx -#endif - -/* - * The following set of definitions characterize the implementation of - * 64-bit Solaris on SPARC V9 systems. - */ -#elif defined(__sparcv9) - -/* - * Define the appropriate "processor characteristics" - */ -#define _LONG_ALIGNMENT 8 -#define _LONG_DOUBLE_ALIGNMENT 16 -#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 16 -#define _POINTER_ALIGNMENT 8 -#define _MAX_ALIGNMENT 16 - -#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGMENT - -/* - * Define the appropriate "implementation choices" - */ -#if !defined(_LP64) -#define _LP64 -#endif -#if !defined(_I32LPx) -#define _I32LPx -#endif -#define _MULTI_DATAMODEL - -#else -#error "unknown SPARC version" -#endif - -/* - * #error is strictly ansi-C, but works as well as anything for K&R systems. - */ -#else -#error "ISA not supported" -#endif - -#if defined(_ILP32) && defined(_LP64) -#error "Both _ILP32 and _LP64 are defined" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_ISA_DEFS_H */ diff --git a/zfs/lib/libsolcompat/include/sys/kmem.h b/zfs/lib/libsolcompat/include/sys/kmem.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/kstat.h b/zfs/lib/libsolcompat/include/sys/kstat.h deleted file mode 100644 index fcd3ed98b..000000000 --- a/zfs/lib/libsolcompat/include/sys/kstat.h +++ /dev/null @@ -1,820 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_KSTAT_H -#define _SYS_KSTAT_H - - - -/* - * Definition of general kernel statistics structures and /dev/kstat ioctls - */ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int kid_t; /* unique kstat id */ - -/* - * Kernel statistics driver (/dev/kstat) ioctls - */ - -#define KSTAT_IOC_BASE ('K' << 8) - -#define KSTAT_IOC_CHAIN_ID KSTAT_IOC_BASE | 0x01 -#define KSTAT_IOC_READ KSTAT_IOC_BASE | 0x02 -#define KSTAT_IOC_WRITE KSTAT_IOC_BASE | 0x03 - -/* - * /dev/kstat ioctl usage (kd denotes /dev/kstat descriptor): - * - * kcid = ioctl(kd, KSTAT_IOC_CHAIN_ID, NULL); - * kcid = ioctl(kd, KSTAT_IOC_READ, kstat_t *); - * kcid = ioctl(kd, KSTAT_IOC_WRITE, kstat_t *); - */ - -#define KSTAT_STRLEN 31 /* 30 chars + NULL; must be 16 * n - 1 */ - -/* - * The generic kstat header - */ - -typedef struct kstat { - /* - * Fields relevant to both kernel and user - */ - hrtime_t ks_crtime; /* creation time (from gethrtime()) */ - struct kstat *ks_next; /* kstat chain linkage */ - kid_t ks_kid; /* unique kstat ID */ - char ks_module[KSTAT_STRLEN]; /* provider module name */ - uchar_t ks_resv; /* reserved, currently just padding */ - int ks_instance; /* provider module's instance */ - char ks_name[KSTAT_STRLEN]; /* kstat name */ - uchar_t ks_type; /* kstat data type */ - char ks_class[KSTAT_STRLEN]; /* kstat class */ - uchar_t ks_flags; /* kstat flags */ - void *ks_data; /* kstat type-specific data */ - uint_t ks_ndata; /* # of type-specific data records */ - size_t ks_data_size; /* total size of kstat data section */ - hrtime_t ks_snaptime; /* time of last data shapshot */ - /* - * Fields relevant to kernel only - */ - int (*ks_update)(struct kstat *, int); /* dynamic update */ - void *ks_private; /* arbitrary provider-private data */ - int (*ks_snapshot)(struct kstat *, void *, int); - void *ks_lock; /* protects this kstat's data */ -} kstat_t; - -#ifdef _SYSCALL32 - -typedef int32_t kid32_t; - -typedef struct kstat32 { - /* - * Fields relevant to both kernel and user - */ - hrtime_t ks_crtime; - caddr32_t ks_next; /* struct kstat pointer */ - kid32_t ks_kid; - char ks_module[KSTAT_STRLEN]; - uint8_t ks_resv; - int32_t ks_instance; - char ks_name[KSTAT_STRLEN]; - uint8_t ks_type; - char ks_class[KSTAT_STRLEN]; - uint8_t ks_flags; - caddr32_t ks_data; /* type-specific data */ - uint32_t ks_ndata; - size32_t ks_data_size; - hrtime_t ks_snaptime; - /* - * Fields relevant to kernel only (only needed here for padding) - */ - int32_t _ks_update; - caddr32_t _ks_private; - int32_t _ks_snapshot; - caddr32_t _ks_lock; -} kstat32_t; - -#endif /* _SYSCALL32 */ - -/* - * kstat structure and locking strategy - * - * Each kstat consists of a header section (a kstat_t) and a data section. - * The system maintains a set of kstats, protected by kstat_chain_lock. - * kstat_chain_lock protects all additions to/deletions from this set, - * as well as all changes to kstat headers. kstat data sections are - * *optionally* protected by the per-kstat ks_lock. If ks_lock is non-NULL, - * kstat clients (e.g. /dev/kstat) will acquire this lock for all of their - * operations on that kstat. It is up to the kstat provider to decide whether - * guaranteeing consistent data to kstat clients is sufficiently important - * to justify the locking cost. Note, however, that most statistic updates - * already occur under one of the provider's mutexes, so if the provider sets - * ks_lock to point to that mutex, then kstat data locking is free. - * - * NOTE: variable-size kstats MUST employ kstat data locking, to prevent - * data-size races with kstat clients. - * - * NOTE: ks_lock is really of type (kmutex_t *); it is declared as (void *) - * in the kstat header so that users don't have to be exposed to all of the - * kernel's lock-related data structures. - */ - -#if defined(_KERNEL) - -#define KSTAT_ENTER(k) \ - { kmutex_t *lp = (k)->ks_lock; if (lp) mutex_enter(lp); } - -#define KSTAT_EXIT(k) \ - { kmutex_t *lp = (k)->ks_lock; if (lp) mutex_exit(lp); } - -#define KSTAT_UPDATE(k, rw) (*(k)->ks_update)((k), (rw)) - -#define KSTAT_SNAPSHOT(k, buf, rw) (*(k)->ks_snapshot)((k), (buf), (rw)) - -#endif /* defined(_KERNEL) */ - -/* - * kstat time - * - * All times associated with kstats (e.g. creation time, snapshot time, - * kstat_timer_t and kstat_io_t timestamps, etc.) are 64-bit nanosecond values, - * as returned by gethrtime(). The accuracy of these timestamps is machine - * dependent, but the precision (units) is the same across all platforms. - */ - -/* - * kstat identity (KID) - * - * Each kstat is assigned a unique KID (kstat ID) when it is added to the - * global kstat chain. The KID is used as a cookie by /dev/kstat to - * request information about the corresponding kstat. There is also - * an identity associated with the entire kstat chain, kstat_chain_id, - * which is bumped each time a kstat is added or deleted. /dev/kstat uses - * the chain ID to detect changes in the kstat chain (e.g., a new disk - * coming online) between ioctl()s. - */ - -/* - * kstat module, kstat instance - * - * ks_module and ks_instance contain the name and instance of the module - * that created the kstat. In cases where there can only be one instance, - * ks_instance is 0. The kernel proper (/kernel/unix) uses "unix" as its - * module name. - */ - -/* - * kstat name - * - * ks_name gives a meaningful name to a kstat. The full kstat namespace - * is module.instance.name, so the name only need be unique within a - * module. kstat_create() will fail if you try to create a kstat with - * an already-used (ks_module, ks_instance, ks_name) triplet. Spaces are - * allowed in kstat names, but strongly discouraged, since they hinder - * awk-style processing at user level. - */ - -/* - * kstat type - * - * The kstat mechanism provides several flavors of kstat data, defined - * below. The "raw" kstat type is just treated as an array of bytes; you - * can use this to export any kind of data you want. - * - * Some kstat types allow multiple data structures per kstat, e.g. - * KSTAT_TYPE_NAMED; others do not. This is part of the spec for each - * kstat data type. - * - * User-level tools should *not* rely on the #define KSTAT_NUM_TYPES. To - * get this information, read out the standard system kstat "kstat_types". - */ - -#define KSTAT_TYPE_RAW 0 /* can be anything */ - /* ks_ndata >= 1 */ -#define KSTAT_TYPE_NAMED 1 /* name/value pair */ - /* ks_ndata >= 1 */ -#define KSTAT_TYPE_INTR 2 /* interrupt statistics */ - /* ks_ndata == 1 */ -#define KSTAT_TYPE_IO 3 /* I/O statistics */ - /* ks_ndata == 1 */ -#define KSTAT_TYPE_TIMER 4 /* event timer */ - /* ks_ndata >= 1 */ - -#define KSTAT_NUM_TYPES 5 - -/* - * kstat class - * - * Each kstat can be characterized as belonging to some broad class - * of statistics, e.g. disk, tape, net, vm, streams, etc. This field - * can be used as a filter to extract related kstats. The following - * values are currently in use: disk, tape, net, controller, vm, kvm, - * hat, streams, kstat, and misc. (The kstat class encompasses things - * like kstat_types.) - */ - -/* - * kstat flags - * - * Any of the following flags may be passed to kstat_create(). They are - * all zero by default. - * - * KSTAT_FLAG_VIRTUAL: - * - * Tells kstat_create() not to allocate memory for the - * kstat data section; instead, you will set the ks_data - * field to point to the data you wish to export. This - * provides a convenient way to export existing data - * structures. - * - * KSTAT_FLAG_VAR_SIZE: - * - * The size of the kstat you are creating will vary over time. - * For example, you may want to use the kstat mechanism to - * export a linked list. NOTE: The kstat framework does not - * manage the data section, so all variable-size kstats must be - * virtual kstats. Moreover, variable-size kstats MUST employ - * kstat data locking to prevent data-size races with kstat - * clients. See the section on "kstat snapshot" for details. - * - * KSTAT_FLAG_WRITABLE: - * - * Makes the kstat's data section writable by root. - * The ks_snapshot routine (see below) does not need to check for - * this; permission checking is handled in the kstat driver. - * - * KSTAT_FLAG_PERSISTENT: - * - * Indicates that this kstat is to be persistent over time. - * For persistent kstats, kstat_delete() simply marks the - * kstat as dormant; a subsequent kstat_create() reactivates - * the kstat. This feature is provided so that statistics - * are not lost across driver close/open (e.g., raw disk I/O - * on a disk with no mounted partitions.) - * NOTE: Persistent kstats cannot be virtual, since ks_data - * points to garbage as soon as the driver goes away. - * - * The following flags are maintained by the kstat framework: - * - * KSTAT_FLAG_DORMANT: - * - * For persistent kstats, indicates that the kstat is in the - * dormant state (e.g., the corresponding device is closed). - * - * KSTAT_FLAG_INVALID: - * - * This flag is set when a kstat is in a transitional state, - * e.g. between kstat_create() and kstat_install(). - * kstat clients must not attempt to access the kstat's data - * if this flag is set. - */ - -#define KSTAT_FLAG_VIRTUAL 0x01 -#define KSTAT_FLAG_VAR_SIZE 0x02 -#define KSTAT_FLAG_WRITABLE 0x04 -#define KSTAT_FLAG_PERSISTENT 0x08 -#define KSTAT_FLAG_DORMANT 0x10 -#define KSTAT_FLAG_INVALID 0x20 - -/* - * Dynamic update support - * - * The kstat mechanism allows for an optional ks_update function to update - * kstat data. This is useful for drivers where the underlying device - * keeps cheap hardware stats, but extraction is expensive. Instead of - * constantly keeping the kstat data section up to date, you can supply a - * ks_update function which updates the kstat's data section on demand. - * To take advantage of this feature, simply set the ks_update field before - * calling kstat_install(). - * - * The ks_update function, if supplied, must have the following structure: - * - * int - * foo_kstat_update(kstat_t *ksp, int rw) - * { - * if (rw == KSTAT_WRITE) { - * ... update the native stats from ksp->ks_data; - * return EACCES if you don't support this - * } else { - * ... update ksp->ks_data from the native stats - * } - * } - * - * The ks_update return codes are: 0 for success, EACCES if you don't allow - * KSTAT_WRITE, and EIO for any other type of error. - * - * In general, the ks_update function may need to refer to provider-private - * data; for example, it may need a pointer to the provider's raw statistics. - * The ks_private field is available for this purpose. Its use is entirely - * at the provider's discretion. - * - * All variable-size kstats MUST supply a ks_update routine, which computes - * and sets ks_data_size (and ks_ndata if that is meaningful), since these - * are needed to perform kstat snapshots (see below). - * - * No kstat locking should be done inside the ks_update routine. The caller - * will already be holding the kstat's ks_lock (to ensure consistent data). - */ - -#define KSTAT_READ 0 -#define KSTAT_WRITE 1 - -/* - * Kstat snapshot - * - * In order to get a consistent view of a kstat's data, clients must obey - * the kstat's locking strategy. However, these clients may need to perform - * operations on the data which could cause a fault (e.g. copyout()), or - * operations which are simply expensive. Doing so could cause deadlock - * (e.g. if you're holding a disk's kstat lock which is ultimately required - * to resolve a copyout() fault), performance degradation (since the providers' - * activity is serialized at the kstat lock), device timing problems, etc. - * - * To avoid these problems, kstat data is provided via snapshots. Taking - * a snapshot is a simple process: allocate a wired-down kernel buffer, - * acquire the kstat's data lock, copy the data into the buffer ("take the - * snapshot"), and release the lock. This ensures that the kstat's data lock - * will be held as briefly as possible, and that no faults will occur while - * the lock is held. - * - * Normally, the snapshot is taken by default_kstat_snapshot(), which - * timestamps the data (sets ks_snaptime), copies it, and does a little - * massaging to deal with incomplete transactions on i/o kstats. However, - * this routine only works for kstats with contiguous data (the typical case). - * If you create a kstat whose data is, say, a linked list, you must provide - * your own ks_snapshot routine. The routine you supply must have the - * following prototype (replace "foo" with something appropriate): - * - * int foo_kstat_snapshot(kstat_t *ksp, void *buf, int rw); - * - * The minimal snapshot routine -- one which copies contiguous data that - * doesn't need any massaging -- would be this: - * - * ksp->ks_snaptime = gethrtime(); - * if (rw == KSTAT_WRITE) - * bcopy(buf, ksp->ks_data, ksp->ks_data_size); - * else - * bcopy(ksp->ks_data, buf, ksp->ks_data_size); - * return (0); - * - * A more illuminating example is taking a snapshot of a linked list: - * - * ksp->ks_snaptime = gethrtime(); - * if (rw == KSTAT_WRITE) - * return (EACCES); ... See below ... - * for (foo = first_foo; foo; foo = foo->next) { - * bcopy((char *) foo, (char *) buf, sizeof (struct foo)); - * buf = ((struct foo *) buf) + 1; - * } - * return (0); - * - * In the example above, we have decided that we don't want to allow - * KSTAT_WRITE access, so we return EACCES if this is attempted. - * - * The key points are: - * - * (1) ks_snaptime must be set (via gethrtime()) to timestamp the data. - * (2) Data gets copied from the kstat to the buffer on KSTAT_READ, - * and from the buffer to the kstat on KSTAT_WRITE. - * (3) ks_snapshot return values are: 0 for success, EACCES if you - * don't allow KSTAT_WRITE, and EIO for any other type of error. - * - * Named kstats (see section on "Named statistics" below) containing long - * strings (KSTAT_DATA_STRING) need special handling. The kstat driver - * assumes that all strings are copied into the buffer after the array of - * named kstats, and the pointers (KSTAT_NAMED_STR_PTR()) are updated to point - * into the copy within the buffer. The default snapshot routine does this, - * but overriding routines should contain at least the following: - * - * if (rw == KSTAT_READ) { - * kstat_named_t *knp = buf; - * char *end = knp + ksp->ks_ndata; - * uint_t i; - * - * ... Do the regular copy ... - * bcopy(ksp->ks_data, buf, sizeof (kstat_named_t) * ksp->ks_ndata); - * - * for (i = 0; i < ksp->ks_ndata; i++, knp++) { - * if (knp[i].data_type == KSTAT_DATA_STRING && - * KSTAT_NAMED_STR_PTR(knp) != NULL) { - * bcopy(KSTAT_NAMED_STR_PTR(knp), end, - * KSTAT_NAMED_STR_BUFLEN(knp)); - * KSTAT_NAMED_STR_PTR(knp) = end; - * end += KSTAT_NAMED_STR_BUFLEN(knp); - * } - * } - */ - -/* - * Named statistics. - * - * List of arbitrary name=value statistics. - */ - -typedef struct kstat_named { - char name[KSTAT_STRLEN]; /* name of counter */ - uchar_t data_type; /* data type */ - union { - char c[16]; /* enough for 128-bit ints */ - int32_t i32; - uint32_t ui32; - struct { - union { - char *ptr; /* NULL-term string */ -#if defined(_KERNEL) && defined(_MULTI_DATAMODEL) - caddr32_t ptr32; -#endif - char __pad[8]; /* 64-bit padding */ - } addr; - uint32_t len; /* # bytes for strlen + '\0' */ - } str; -/* - * The int64_t and uint64_t types are not valid for a maximally conformant - * 32-bit compilation environment (cc -Xc) using compilers prior to the - * introduction of C99 conforming compiler (reference ISO/IEC 9899:1990). - * In these cases, the visibility of i64 and ui64 is only permitted for - * 64-bit compilation environments or 32-bit non-maximally conformant - * C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the - * C99 ANSI C compilation environment, the long long type is supported. - * The _INT64_TYPE is defined by the implementation (see sys/int_types.h). - */ -#if defined(_INT64_TYPE) - int64_t i64; - uint64_t ui64; -#endif - long l; - ulong_t ul; - - /* These structure members are obsolete */ - - longlong_t ll; - u_longlong_t ull; - float f; - double d; - } value; /* value of counter */ -} kstat_named_t; - -#define KSTAT_DATA_CHAR 0 -#define KSTAT_DATA_INT32 1 -#define KSTAT_DATA_UINT32 2 -#define KSTAT_DATA_INT64 3 -#define KSTAT_DATA_UINT64 4 - -#if !defined(_LP64) -#define KSTAT_DATA_LONG KSTAT_DATA_INT32 -#define KSTAT_DATA_ULONG KSTAT_DATA_UINT32 -#else -#if !defined(_KERNEL) -#define KSTAT_DATA_LONG KSTAT_DATA_INT64 -#define KSTAT_DATA_ULONG KSTAT_DATA_UINT64 -#else -#define KSTAT_DATA_LONG 7 /* only visible to the kernel */ -#define KSTAT_DATA_ULONG 8 /* only visible to the kernel */ -#endif /* !_KERNEL */ -#endif /* !_LP64 */ - -/* - * Statistics exporting named kstats with long strings (KSTAT_DATA_STRING) - * may not make the assumption that ks_data_size is equal to (ks_ndata * sizeof - * (kstat_named_t)). ks_data_size in these cases is equal to the sum of the - * amount of space required to store the strings (ie, the sum of - * KSTAT_NAMED_STR_BUFLEN() for all KSTAT_DATA_STRING statistics) plus the - * space required to store the kstat_named_t's. - * - * The default update routine will update ks_data_size automatically for - * variable-length kstats containing long strings (using the default update - * routine only makes sense if the string is the only thing that is changing - * in size, and ks_ndata is constant). Fixed-length kstats containing long - * strings must explicitly change ks_data_size (after creation but before - * initialization) to reflect the correct amount of space required for the - * long strings and the kstat_named_t's. - */ -#define KSTAT_DATA_STRING 9 - -/* These types are obsolete */ - -#define KSTAT_DATA_LONGLONG KSTAT_DATA_INT64 -#define KSTAT_DATA_ULONGLONG KSTAT_DATA_UINT64 -#define KSTAT_DATA_FLOAT 5 -#define KSTAT_DATA_DOUBLE 6 - -#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data) - -/* - * Retrieve the pointer of the string contained in the given named kstat. - */ -#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr) - -/* - * Retrieve the length of the buffer required to store the string in the given - * named kstat. - */ -#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len) - -/* - * Interrupt statistics. - * - * An interrupt is a hard interrupt (sourced from the hardware device - * itself), a soft interrupt (induced by the system via the use of - * some system interrupt source), a watchdog interrupt (induced by - * a periodic timer call), spurious (an interrupt entry point was - * entered but there was no interrupt condition to service), - * or multiple service (an interrupt condition was detected and - * serviced just prior to returning from any of the other types). - * - * Measurement of the spurious class of interrupts is useful for - * autovectored devices in order to pinpoint any interrupt latency - * problems in a particular system configuration. - * - * Devices that have more than one interrupt of the same - * type should use multiple structures. - */ - -#define KSTAT_INTR_HARD 0 -#define KSTAT_INTR_SOFT 1 -#define KSTAT_INTR_WATCHDOG 2 -#define KSTAT_INTR_SPURIOUS 3 -#define KSTAT_INTR_MULTSVC 4 - -#define KSTAT_NUM_INTRS 5 - -typedef struct kstat_intr { - uint_t intrs[KSTAT_NUM_INTRS]; /* interrupt counters */ -} kstat_intr_t; - -#define KSTAT_INTR_PTR(kptr) ((kstat_intr_t *)(kptr)->ks_data) - -/* - * I/O statistics. - */ - -typedef struct kstat_io { - - /* - * Basic counters. - * - * The counters should be updated at the end of service - * (e.g., just prior to calling biodone()). - */ - - u_longlong_t nread; /* number of bytes read */ - u_longlong_t nwritten; /* number of bytes written */ - uint_t reads; /* number of read operations */ - uint_t writes; /* number of write operations */ - - /* - * Accumulated time and queue length statistics. - * - * Accumulated time statistics are kept as a running sum - * of "active" time. Queue length statistics are kept as a - * running sum of the product of queue length and elapsed time - * at that length -- i.e., a Riemann sum for queue length - * integrated against time. (You can also think of the active time - * as a Riemann sum, for the boolean function (queue_length > 0) - * integrated against time, or you can think of it as the - * Lebesgue measure of the set on which queue_length > 0.) - * - * ^ - * | _________ - * 8 | i4 | - * | | | - * Queue 6 | | - * Length | _________ | | - * 4 | i2 |_______| | - * | | i3 | - * 2_______| | - * | i1 | - * |_______________________________| - * Time-> t1 t2 t3 t4 - * - * At each change of state (entry or exit from the queue), - * we add the elapsed time (since the previous state change) - * to the active time if the queue length was non-zero during - * that interval; and we add the product of the elapsed time - * times the queue length to the running length*time sum. - * - * This method is generalizable to measuring residency - * in any defined system: instead of queue lengths, think - * of "outstanding RPC calls to server X". - * - * A large number of I/O subsystems have at least two basic - * "lists" of transactions they manage: one for transactions - * that have been accepted for processing but for which processing - * has yet to begin, and one for transactions which are actively - * being processed (but not done). For this reason, two cumulative - * time statistics are defined here: wait (pre-service) time, - * and run (service) time. - * - * All times are 64-bit nanoseconds (hrtime_t), as returned by - * gethrtime(). - * - * The units of cumulative busy time are accumulated nanoseconds. - * The units of cumulative length*time products are elapsed time - * times queue length. - * - * Updates to the fields below are performed implicitly by calls to - * these five functions: - * - * kstat_waitq_enter() - * kstat_waitq_exit() - * kstat_runq_enter() - * kstat_runq_exit() - * - * kstat_waitq_to_runq() (see below) - * kstat_runq_back_to_waitq() (see below) - * - * Since kstat_waitq_exit() is typically followed immediately - * by kstat_runq_enter(), there is a single kstat_waitq_to_runq() - * function which performs both operations. This is a performance - * win since only one timestamp is required. - * - * In some instances, it may be necessary to move a request from - * the run queue back to the wait queue, e.g. for write throttling. - * For these situations, call kstat_runq_back_to_waitq(). - * - * These fields should never be updated by any other means. - */ - - hrtime_t wtime; /* cumulative wait (pre-service) time */ - hrtime_t wlentime; /* cumulative wait length*time product */ - hrtime_t wlastupdate; /* last time wait queue changed */ - hrtime_t rtime; /* cumulative run (service) time */ - hrtime_t rlentime; /* cumulative run length*time product */ - hrtime_t rlastupdate; /* last time run queue changed */ - - uint_t wcnt; /* count of elements in wait state */ - uint_t rcnt; /* count of elements in run state */ - -} kstat_io_t; - -#define KSTAT_IO_PTR(kptr) ((kstat_io_t *)(kptr)->ks_data) - -/* - * Event timer statistics - cumulative elapsed time and number of events. - * - * Updates to these fields are performed implicitly by calls to - * kstat_timer_start() and kstat_timer_stop(). - */ - -typedef struct kstat_timer { - char name[KSTAT_STRLEN]; /* event name */ - uchar_t resv; /* reserved */ - u_longlong_t num_events; /* number of events */ - hrtime_t elapsed_time; /* cumulative elapsed time */ - hrtime_t min_time; /* shortest event duration */ - hrtime_t max_time; /* longest event duration */ - hrtime_t start_time; /* previous event start time */ - hrtime_t stop_time; /* previous event stop time */ -} kstat_timer_t; - -#define KSTAT_TIMER_PTR(kptr) ((kstat_timer_t *)(kptr)->ks_data) - -#if defined(_KERNEL) - -#include - -extern kid_t kstat_chain_id; /* bumped at each state change */ -extern void kstat_init(void); /* initialize kstat framework */ - -/* - * Adding and deleting kstats. - * - * The typical sequence to add a kstat is: - * - * ksp = kstat_create(module, instance, name, class, type, ndata, flags); - * if (ksp) { - * ... provider initialization, if necessary - * kstat_install(ksp); - * } - * - * There are three logically distinct steps here: - * - * Step 1: System Initialization (kstat_create) - * - * kstat_create() performs system initialization. kstat_create() - * allocates memory for the entire kstat (header plus data), initializes - * all header fields, initializes the data section to all zeroes, assigns - * a unique KID, and puts the kstat onto the system's kstat chain. - * The returned kstat is marked invalid (KSTAT_FLAG_INVALID is set), - * because the provider (caller) has not yet had a chance to initialize - * the data section. - * - * By default, kstats are exported to all zones on the system. A kstat may be - * created via kstat_create_zone() to specify a zone to which the statistics - * should be exported. kstat_zone_add() may be used to specify additional - * zones to which the statistics are to be exported. - * - * Step 2: Provider Initialization - * - * The provider performs any necessary initialization of the data section, - * e.g. setting the name fields in a KSTAT_TYPE_NAMED. Virtual kstats set - * the ks_data field at this time. The provider may also set the ks_update, - * ks_snapshot, ks_private, and ks_lock fields if necessary. - * - * Step 3: Installation (kstat_install) - * - * Once the kstat is completely initialized, kstat_install() clears the - * INVALID flag, thus making the kstat accessible to the outside world. - * kstat_install() also clears the DORMANT flag for persistent kstats. - * - * Removing a kstat from the system - * - * kstat_delete(ksp) removes ksp from the kstat chain and frees all - * associated system resources. NOTE: When you call kstat_delete(), - * you must NOT be holding that kstat's ks_lock. Otherwise, you may - * deadlock with a kstat reader. - * - * Persistent kstats - * - * From the provider's point of view, persistence is transparent. The only - * difference between ephemeral (normal) kstats and persistent kstats - * is that you pass KSTAT_FLAG_PERSISTENT to kstat_create(). Magically, - * this has the effect of making your data visible even when you're - * not home. Persistence is important to tools like iostat, which want - * to get a meaningful picture of disk activity. Without persistence, - * raw disk i/o statistics could never accumulate: they would come and - * go with each open/close of the raw device. - * - * The magic of persistence works by slightly altering the behavior of - * kstat_create() and kstat_delete(). The first call to kstat_create() - * creates a new kstat, as usual. However, kstat_delete() does not - * actually delete the kstat: it performs one final update of the data - * (i.e., calls the ks_update routine), marks the kstat as dormant, and - * sets the ks_lock, ks_update, ks_private, and ks_snapshot fields back - * to their default values (since they might otherwise point to garbage, - * e.g. if the provider is going away). kstat clients can still access - * the dormant kstat just like a live kstat; they just continue to see - * the final data values as long as the kstat remains dormant. - * All subsequent kstat_create() calls simply find the already-existing, - * dormant kstat and return a pointer to it, without altering any fields. - * The provider then performs its usual initialization sequence, and - * calls kstat_install(). kstat_install() uses the old data values to - * initialize the native data (i.e., ks_update is called with KSTAT_WRITE), - * thus making it seem like you were never gone. - */ - -extern kstat_t *kstat_create(const char *, int, const char *, const char *, - uchar_t, uint_t, uchar_t); -extern kstat_t *kstat_create_zone(const char *, int, const char *, - const char *, uchar_t, uint_t, uchar_t, zoneid_t); -extern void kstat_install(kstat_t *); -extern void kstat_delete(kstat_t *); -extern void kstat_named_setstr(kstat_named_t *knp, const char *src); -extern void kstat_set_string(char *, const char *); -extern void kstat_delete_byname(const char *, int, const char *); -extern void kstat_delete_byname_zone(const char *, int, const char *, zoneid_t); -extern void kstat_named_init(kstat_named_t *, const char *, uchar_t); -extern void kstat_timer_init(kstat_timer_t *, const char *); -extern void kstat_waitq_enter(kstat_io_t *); -extern void kstat_waitq_exit(kstat_io_t *); -extern void kstat_runq_enter(kstat_io_t *); -extern void kstat_runq_exit(kstat_io_t *); -extern void kstat_waitq_to_runq(kstat_io_t *); -extern void kstat_runq_back_to_waitq(kstat_io_t *); -extern void kstat_timer_start(kstat_timer_t *); -extern void kstat_timer_stop(kstat_timer_t *); - -extern void kstat_zone_add(kstat_t *, zoneid_t); -extern void kstat_zone_remove(kstat_t *, zoneid_t); -extern int kstat_zone_find(kstat_t *, zoneid_t); - -extern kstat_t *kstat_hold_bykid(kid_t kid, zoneid_t); -extern kstat_t *kstat_hold_byname(const char *, int, const char *, zoneid_t); -extern void kstat_rele(kstat_t *); - -#endif /* defined(_KERNEL) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_KSTAT_H */ diff --git a/zfs/lib/libsolcompat/include/sys/mkdev.h b/zfs/lib/libsolcompat/include/sys/mkdev.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/mntent.h b/zfs/lib/libsolcompat/include/sys/mntent.h deleted file mode 100644 index c0594ca7b..000000000 --- a/zfs/lib/libsolcompat/include/sys/mntent.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T - * All Rights Reserved - */ - -#ifndef _SYS_MNTENT_H -#define _SYS_MNTENT_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -#define MNTTAB "/proc/mounts" -#define VFSTAB "/etc/vfstab" -#define MNTMAXSTR 128 - -#define MNTTYPE_ZFS "zfs" /* ZFS file system */ -#define MNTTYPE_UFS "ufs" /* Unix file system */ -#define MNTTYPE_SMBFS "smbfs" /* SMBFS file system */ -#define MNTTYPE_NFS "nfs" /* NFS file system */ -#define MNTTYPE_NFS3 "nfs3" /* NFS Version 3 file system */ -#define MNTTYPE_NFS4 "nfs4" /* NFS Version 4 file system */ -#define MNTTYPE_CACHEFS "cachefs" /* Cache File System */ -#define MNTTYPE_PCFS "pcfs" /* PC (MSDOS) file system */ -#define MNTTYPE_PC MNTTYPE_PCFS /* Deprecated name; use MNTTYPE_PCFS */ -#define MNTTYPE_LOFS "lofs" /* Loop back file system */ -#define MNTTYPE_LO MNTTYPE_LOFS /* Deprecated name; use MNTTYPE_LOFS */ -#define MNTTYPE_HSFS "hsfs" /* High Sierra (9660) file system */ -#define MNTTYPE_SWAP "swap" /* Swap file system */ -#define MNTTYPE_TMPFS "tmpfs" /* Tmp volatile file system */ -#define MNTTYPE_AUTOFS "autofs" /* Automounter ``file'' system */ -#define MNTTYPE_MNTFS "mntfs" /* In-kernel mnttab */ -#define MNTTYPE_DEV "dev" /* /dev file system */ -#define MNTTYPE_CTFS "ctfs" /* Contract file system */ -#define MNTTYPE_OBJFS "objfs" /* Kernel object file system */ -#define MNTTYPE_SHAREFS "sharefs" /* Kernel sharetab file system */ - - -#define MNTOPT_RO "ro" /* Read only */ -#define MNTOPT_RW "rw" /* Read/write */ -#define MNTOPT_RQ "rq" /* Read/write with quotas */ -#define MNTOPT_QUOTA "quota" /* Check quotas */ -#define MNTOPT_NOQUOTA "noquota" /* Don't check quotas */ -#define MNTOPT_ONERROR "onerror" /* action to taken on error */ -#define MNTOPT_SOFT "soft" /* Soft mount */ -#define MNTOPT_SEMISOFT "semisoft" /* partial soft, uncommited interface */ -#define MNTOPT_HARD "hard" /* Hard mount */ -#define MNTOPT_SUID "suid" /* Both setuid and devices allowed */ -#define MNTOPT_NOSUID "nosuid" /* Neither setuid nor devices allowed */ -#define MNTOPT_DEVICES "devices" /* Device-special allowed */ -#define MNTOPT_NODEVICES "nodevices" /* Device-special disallowed */ -#define MNTOPT_SETUID "setuid" /* Set uid allowed */ -#define MNTOPT_NOSETUID "nosetuid" /* Set uid not allowed */ -#define MNTOPT_GRPID "grpid" /* SysV-compatible gid on create */ -#define MNTOPT_REMOUNT "remount" /* Change mount options */ -#define MNTOPT_NOSUB "nosub" /* Disallow mounts on subdirs */ -#define MNTOPT_MULTI "multi" /* Do multi-component lookup */ -#define MNTOPT_INTR "intr" /* Allow NFS ops to be interrupted */ -#define MNTOPT_NOINTR "nointr" /* Don't allow interrupted ops */ -#define MNTOPT_PORT "port" /* NFS server IP port number */ -#define MNTOPT_SECURE "secure" /* Secure (AUTH_DES) mounting */ -#define MNTOPT_RSIZE "rsize" /* Max NFS read size (bytes) */ -#define MNTOPT_WSIZE "wsize" /* Max NFS write size (bytes) */ -#define MNTOPT_TIMEO "timeo" /* NFS timeout (1/10 sec) */ -#define MNTOPT_RETRANS "retrans" /* Max retransmissions (soft mnts) */ -#define MNTOPT_ACTIMEO "actimeo" /* Attr cache timeout (sec) */ -#define MNTOPT_ACREGMIN "acregmin" /* Min attr cache timeout (files) */ -#define MNTOPT_ACREGMAX "acregmax" /* Max attr cache timeout (files) */ -#define MNTOPT_ACDIRMIN "acdirmin" /* Min attr cache timeout (dirs) */ -#define MNTOPT_ACDIRMAX "acdirmax" /* Max attr cache timeout (dirs) */ -#define MNTOPT_NOAC "noac" /* Don't cache attributes at all */ -#define MNTOPT_NOCTO "nocto" /* No close-to-open consistency */ -#define MNTOPT_BG "bg" /* Do mount retries in background */ -#define MNTOPT_FG "fg" /* Do mount retries in foreground */ -#define MNTOPT_RETRY "retry" /* Number of mount retries */ -#define MNTOPT_DEV "dev" /* Device id of mounted fs */ -#define MNTOPT_POSIX "posix" /* Get static pathconf for mount */ -#define MNTOPT_MAP "map" /* Automount map */ -#define MNTOPT_DIRECT "direct" /* Automount direct map mount */ -#define MNTOPT_INDIRECT "indirect" /* Automount indirect map mount */ -#define MNTOPT_LLOCK "llock" /* Local locking (no lock manager) */ -#define MNTOPT_IGNORE "ignore" /* Ignore this entry */ -#define MNTOPT_VERS "vers" /* protocol version number indicator */ -#define MNTOPT_PROTO "proto" /* protocol network_id indicator */ -#define MNTOPT_SEC "sec" /* Security flavor indicator */ -#define MNTOPT_SYNCDIR "syncdir" /* Synchronous local directory ops */ -#define MNTOPT_NOSETSEC "nosec" /* Do no allow setting sec attrs */ -#define MNTOPT_NOPRINT "noprint" /* Do not print messages */ -#define MNTOPT_LARGEFILES "largefiles" /* allow large files */ -#define MNTOPT_NOLARGEFILES "nolargefiles" /* don't allow large files */ -#define MNTOPT_FORCEDIRECTIO "forcedirectio" /* Force DirectIO on all files */ -#define MNTOPT_NOFORCEDIRECTIO "noforcedirectio" /* No Force DirectIO */ -#define MNTOPT_DISABLEDIRECTIO "disabledirectio" /* Disable DirectIO ioctls */ -#define MNTOPT_PUBLIC "public" /* Use NFS public file handlee */ -#define MNTOPT_LOGGING "logging" /* enable logging */ -#define MNTOPT_NOLOGGING "nologging" /* disable logging */ -#define MNTOPT_ATIME "atime" /* update atime for files */ -#define MNTOPT_NOATIME "noatime" /* do not update atime for files */ -#define MNTOPT_GLOBAL "global" /* Cluster-wide global mount */ -#define MNTOPT_NOGLOBAL "noglobal" /* Mount local to single node */ -#define MNTOPT_DFRATIME "dfratime" /* Deferred access time updates */ -#define MNTOPT_NODFRATIME "nodfratime" /* No Deferred access time updates */ -#define MNTOPT_NBMAND "nbmand" /* allow non-blocking mandatory locks */ -#define MNTOPT_NONBMAND "nonbmand" /* deny non-blocking mandatory locks */ -#define MNTOPT_XATTR "xattr" /* enable extended attributes */ -#define MNTOPT_NOXATTR "noxattr" /* disable extended attributes */ -#define MNTOPT_EXEC "exec" /* enable executables */ -#define MNTOPT_NOEXEC "noexec" /* disable executables */ -#define MNTOPT_RESTRICT "restrict" /* restricted autofs mount */ -#define MNTOPT_BROWSE "browse" /* browsable autofs mount */ -#define MNTOPT_NOBROWSE "nobrowse" /* non-browsable autofs mount */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_MNTENT_H */ diff --git a/zfs/lib/libsolcompat/include/sys/mntio.h b/zfs/lib/libsolcompat/include/sys/mntio.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/mnttab.h b/zfs/lib/libsolcompat/include/sys/mnttab.h deleted file mode 100644 index 70f144967..000000000 --- a/zfs/lib/libsolcompat/include/sys/mnttab.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T*/ -/* All Rights Reserved */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* Copyright 2006 Ricardo Correia */ - -#ifndef _SYS_MNTTAB_H -#define _SYS_MNTTAB_H - -#include -#include -#include - -#ifdef MNTTAB -#undef MNTTAB -#endif - -#define MNTTAB "/proc/mounts" -#define MNT_LINE_MAX 1024 - -#define MNT_TOOLONG 1 /* entry exceeds MNT_LINE_MAX */ -#define MNT_TOOMANY 2 /* too many fields in line */ -#define MNT_TOOFEW 3 /* too few fields in line */ - -struct mnttab { - char *mnt_special; - char *mnt_mountp; - char *mnt_fstype; - char *mnt_mntopts; -}; - -/* - * NOTE: fields in extmnttab should match struct mnttab till new fields - * are encountered, this allows hasmntopt to work properly when its arg is - * a pointer to an extmnttab struct cast to a mnttab struct pointer. - */ - -struct extmnttab { - char *mnt_special; - char *mnt_mountp; - char *mnt_fstype; - char *mnt_mntopts; - uint_t mnt_major; - uint_t mnt_minor; -}; - -extern int getmntany(FILE *fp, struct mnttab *mp, struct mnttab *mpref); -extern int _sol_getmntent(FILE *fp, struct mnttab *mp); -extern int getextmntent(FILE *fp, struct extmnttab *mp, int len); - -static inline char *_sol_hasmntopt(struct mnttab *mnt, char *opt) -{ - struct mntent mnt_new; - - mnt_new.mnt_opts = mnt->mnt_mntopts; - - return hasmntopt(&mnt_new, opt); -} - -#define hasmntopt _sol_hasmntopt -#define getmntent _sol_getmntent - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/modctl.h b/zfs/lib/libsolcompat/include/sys/modctl.h deleted file mode 100644 index afa3a3cca..000000000 --- a/zfs/lib/libsolcompat/include/sys/modctl.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/zfs/lib/libsolcompat/include/sys/note.h b/zfs/lib/libsolcompat/include/sys/note.h deleted file mode 100644 index 88e0eabcd..000000000 --- a/zfs/lib/libsolcompat/include/sys/note.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1994 by Sun Microsystems, Inc. - */ - -/* - * sys/note.h: interface for annotating source with info for tools - * - * This is the underlying interface; NOTE (/usr/include/note.h) is the - * preferred interface, but all exported header files should include this - * file directly and use _NOTE so as not to take "NOTE" from the user's - * namespace. For consistency, *all* kernel source should use _NOTE. - * - * By default, annotations expand to nothing. This file implements - * that. Tools using annotations will interpose a different version - * of this file that will expand annotations as needed. - */ - -#ifndef _SYS_NOTE_H -#define _SYS_NOTE_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _NOTE -#define _NOTE(s) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_NOTE_H */ diff --git a/zfs/lib/libsolcompat/include/sys/param.h b/zfs/lib/libsolcompat/include/sys/param.h deleted file mode 100644 index a0576266b..000000000 --- a/zfs/lib/libsolcompat/include/sys/param.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_PARAM_H -#define _SOL_SYS_PARAM_H - -#include_next -#include - -/* - * File system parameters and macros. - * - * The file system is made out of blocks of at most MAXBSIZE units, - * with smaller units (fragments) only in the last direct block. - * MAXBSIZE primarily determines the size of buffers in the buffer - * pool. It may be made larger without any effect on existing - * file systems; however making it smaller make make some file - * systems unmountable. - * - * Note that the blocked devices are assumed to have DEV_BSIZE - * "sectors" and that fragments must be some multiple of this size. - */ -#define MAXBSIZE 8192 -#define DEV_BSIZE 512 -#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ - -#define MAXNAMELEN 256 -#define MAXOFFSET_T 0x7fffffffffffffffl - -#define UID_NOBODY 60001 /* user ID no body */ -#define GID_NOBODY UID_NOBODY -#define UID_NOACCESS 60002 /* user ID no access */ - -#define MAXUID 2147483647 /* max user id */ -#define MAXPROJID MAXUID /* max project id */ - -#define PAGESIZE (sysconf(_SC_PAGESIZE)) - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/priv.h b/zfs/lib/libsolcompat/include/sys/priv.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/processor.h b/zfs/lib/libsolcompat/include/sys/processor.h deleted file mode 100644 index b00c1eb82..000000000 --- a/zfs/lib/libsolcompat/include/sys/processor.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_PROCESSOR_H -#define _SOL_SYS_PROCESSOR_H - -#define getcpuid() (-1) - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/rctl.h b/zfs/lib/libsolcompat/include/sys/rctl.h deleted file mode 100644 index 0d032e8e3..000000000 --- a/zfs/lib/libsolcompat/include/sys/rctl.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/zfs/lib/libsolcompat/include/sys/sdt.h b/zfs/lib/libsolcompat/include/sys/sdt.h deleted file mode 100644 index e194402a2..000000000 --- a/zfs/lib/libsolcompat/include/sys/sdt.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_SDT_H -#define _SOL_SYS_SDT_H - -#define DTRACE_PROBE1(a,b,c) ((void) 0) -#define DTRACE_PROBE2(a,b,c,d,e) ((void) 0) -#define DTRACE_PROBE3(a,b,c,d,e,f,g) ((void) 0) -#define DTRACE_PROBE4(a,b,c,d,e,f,g,h,i) ((void) 0) - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/stack.h b/zfs/lib/libsolcompat/include/sys/stack.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/stat.h b/zfs/lib/libsolcompat/include/sys/stat.h deleted file mode 100644 index d4db8d358..000000000 --- a/zfs/lib/libsolcompat/include/sys/stat.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Ricardo Correia. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_STAT_H -#define _SOL_STAT_H - -#include_next - -#include -#include -#include - -/* LINUX */ -#include -#include - -static inline int zfsfuse_fstat64(int fd, struct stat64 *buf) -{ - if(fstat64(fd, buf) == -1) - return -1; - - if(S_ISBLK(buf->st_mode)) { - /* LINUX */ - uint64_t size; - if(real_ioctl(fd, BLKGETSIZE64, &size) != 0) { - fprintf(stderr, "failed to read device size: %s\n", strerror(errno)); - return 0; - } - buf->st_size = size; - } - - return 0; -} - -#define fstat64(fd, buf) zfsfuse_fstat64(fd, buf) - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/sunddi.h b/zfs/lib/libsolcompat/include/sys/sunddi.h deleted file mode 100644 index 5c245d339..000000000 --- a/zfs/lib/libsolcompat/include/sys/sunddi.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SUNDDI_H -#define _SOL_SUNDDI_H - -#ifdef _KERNEL - -#include -#include - -#include - -static inline int -ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result) -{ - char *end; - - *result = strtoul(hw_serial, &end, base); - if (*result == 0) - return (errno); - return (0); -} -#endif - -#endif - diff --git a/zfs/lib/libsolcompat/include/sys/sysevent.h b/zfs/lib/libsolcompat/include/sys/sysevent.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/sysevent/eventdefs.h b/zfs/lib/libsolcompat/include/sys/sysevent/eventdefs.h deleted file mode 100644 index c4494f778..000000000 --- a/zfs/lib/libsolcompat/include/sys/sysevent/eventdefs.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_SYSEVENT_EVENTDEFS_H -#define _SYS_SYSEVENT_EVENTDEFS_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * eventdefs.h contains public definitions for sysevent types (classes - * and subclasses). All additions/removal/changes are subject - * to PSARC approval. - */ - -/* Sysevent Class definitions */ -#define EC_NONE "EC_none" -#define EC_PRIV "EC_priv" -#define EC_PLATFORM "EC_platform" /* events private to platform */ -#define EC_DR "EC_dr" /* Dynamic reconfiguration event class */ -#define EC_ENV "EC_env" /* Environmental monitor event class */ -#define EC_DOMAIN "EC_domain" /* Domain event class */ -#define EC_AP_DRIVER "EC_ap_driver" /* Alternate Pathing event class */ -#define EC_IPMP "EC_ipmp" /* IP Multipathing event class */ -#define EC_DEV_ADD "EC_dev_add" /* device add event class */ -#define EC_DEV_REMOVE "EC_dev_remove" /* device remove event class */ -#define EC_DEV_BRANCH "EC_dev_branch" /* device tree branch event class */ -#define EC_FM "EC_fm" /* FMA error report event */ -#define EC_ZFS "EC_zfs" /* ZFS event */ - -/* - * The following event class is reserved for exclusive use - * by Sun Cluster software. - */ -#define EC_CLUSTER "EC_Cluster" - -/* - * The following classes are exclusively reserved for use by the - * Solaris Volume Manager (SVM) - */ -#define EC_SVM_CONFIG "EC_SVM_Config" -#define EC_SVM_STATE "EC_SVM_State" - -/* - * EC_SVM_CONFIG subclass definitions - supporting attributes (name/value pairs) - * are found in sys/sysevent/svm.h - */ -#define ESC_SVM_CREATE "ESC_SVM_Create" -#define ESC_SVM_DELETE "ESC_SVM_Delete" -#define ESC_SVM_ADD "ESC_SVM_Add" -#define ESC_SVM_REMOVE "ESC_SVM_Remove" -#define ESC_SVM_REPLACE "ESC_SVM_Replace" -#define ESC_SVM_GROW "ESC_SVM_Grow" -#define ESC_SVM_RENAME_SRC "ESC_SVM_Rename_Src" -#define ESC_SVM_RENAME_DST "ESC_SVM_Rename_Dst" -#define ESC_SVM_MEDIATOR_ADD "ESC_SVM_Mediator_Add" -#define ESC_SVM_MEDIATOR_DELETE "ESC_SVM_Mediator_Delete" -#define ESC_SVM_HOST_ADD "ESC_SVM_Host_Add" -#define ESC_SVM_HOST_DELETE "ESC_SVM_Host_Delete" -#define ESC_SVM_DRIVE_ADD "ESC_SVM_Drive_Add" -#define ESC_SVM_DRIVE_DELETE "ESC_SVM_Drive_Delete" -#define ESC_SVM_DETACH "ESC_SVM_Detach" -#define ESC_SVM_DETACHING "ESC_SVM_Detaching" -#define ESC_SVM_ATTACH "ESC_SVM_Attach" -#define ESC_SVM_ATTACHING "ESC_SVM_Attaching" - -/* - * EC_SVM_STATE subclass definitions - supporting attributes (name/value pairs) - * are found in sys/sysevent/svm.h - */ -#define ESC_SVM_INIT_START "ESC_SVM_Init_Start" -#define ESC_SVM_INIT_FAILED "ESC_SVM_Init_Failed" -#define ESC_SVM_INIT_FATAL "ESC_SVM_Init_Fatal" -#define ESC_SVM_INIT_SUCCESS "ESC_SVM_Init_Success" -#define ESC_SVM_IOERR "ESC_SVM_Ioerr" -#define ESC_SVM_ERRED "ESC_SVM_Erred" -#define ESC_SVM_LASTERRED "ESC_SVM_Lasterred" -#define ESC_SVM_OK "ESC_SVM_Ok" -#define ESC_SVM_ENABLE "ESC_SVM_Enable" -#define ESC_SVM_RESYNC_START "ESC_SVM_Resync_Start" -#define ESC_SVM_RESYNC_FAILED "ESC_SVM_Resync_Failed" -#define ESC_SVM_RESYNC_SUCCESS "ESC_SVM_Resync_Success" -#define ESC_SVM_RESYNC_DONE "ESC_SVM_Resync_Done" -#define ESC_SVM_HOTSPARED "ESC_SVM_Hotspared" -#define ESC_SVM_HS_FREED "ESC_SVM_HS_Freed" -#define ESC_SVM_HS_CHANGED "ESC_SVM_HS_Changed" -#define ESC_SVM_TAKEOVER "ESC_SVM_Takeover" -#define ESC_SVM_RELEASE "ESC_SVM_Release" -#define ESC_SVM_OPEN_FAIL "ESC_SVM_Open_Fail" -#define ESC_SVM_OFFLINE "ESC_SVM_Offline" -#define ESC_SVM_ONLINE "ESC_SVM_Online" -#define ESC_SVM_CHANGE "ESC_SVM_Change" -#define ESC_SVM_EXCHANGE "ESC_SVM_Exchange" -#define ESC_SVM_REGEN_START "ESC_SVM_Regen_Start" -#define ESC_SVM_REGEN_DONE "ESC_SVM_Regen_Done" -#define ESC_SVM_REGEN_FAILED "ESC_SVM_Regen_Failed" - -/* - * EC_DR subclass definitions - supporting attributes (name/value pairs) - * are found in sys/sysevent/dr.h - */ - -/* Attachment point state change */ -#define ESC_DR_AP_STATE_CHANGE "ESC_dr_ap_state_change" -#define ESC_DR_REQ "ESC_dr_req" /* Request DR */ -#define ESC_DR_TARGET_STATE_CHANGE "ESC_dr_target_state_change" - -/* - * EC_ENV subclass definitions - supporting attributes (name/value pairs) - * are found in sys/sysevent/env.h - */ -#define ESC_ENV_TEMP "ESC_env_temp" /* Temperature change event subclass */ -#define ESC_ENV_FAN "ESC_env_fan" /* Fan status change event subclass */ -#define ESC_ENV_POWER "ESC_env_power" /* Power supply change event subclass */ -#define ESC_ENV_LED "ESC_env_led" /* LED change event subclass */ - -/* - * EC_DOMAIN subclass definitions - supporting attributes (name/value pairs) - * are found in sys/sysevent/domain.h - */ - -/* Domain state change */ -#define ESC_DOMAIN_STATE_CHANGE "ESC_domain_state_change" -/* Domain loghost name change */ -#define ESC_DOMAIN_LOGHOST_CHANGE "ESC_domain_loghost_change" - -/* - * EC_AP_DRIVER subclass definitions - supporting attributes (name/value pairs) - * are found in sys/sysevent/ap_driver.h - */ - -/* Alternate Pathing path switch */ -#define ESC_AP_DRIVER_PATHSWITCH "ESC_ap_driver_pathswitch" -/* Alternate Pathing database commit */ -#define ESC_AP_DRIVER_COMMIT "ESC_ap_driver_commit" -/* Alternate Pathing physical path status change */ -#define ESC_AP_DRIVER_PHYS_PATH_STATUS_CHANGE \ - "ESC_ap_driver_phys_path_status_change" - -/* - * EC_IPMP subclass definitions - supporting attributes (name/value pairs) - * are found in sys/sysevent/ipmp.h - */ - -/* IPMP group has changed state */ -#define ESC_IPMP_GROUP_STATE "ESC_ipmp_group_state" - -/* IPMP group has been created or removed */ -#define ESC_IPMP_GROUP_CHANGE "ESC_ipmp_group_change" - -/* IPMP group has had an interface added or removed */ -#define ESC_IPMP_GROUP_MEMBER_CHANGE "ESC_ipmp_group_member_change" - -/* Interface within an IPMP group has changed state or type */ -#define ESC_IPMP_IF_CHANGE "ESC_ipmp_if_change" - - -/* - * EC_DEV_ADD and EC_DEV_REMOVE subclass definitions - supporting attributes - * (name/value pairs) are found in sys/sysevent/dev.h - */ -#define ESC_DISK "disk" /* disk device */ -#define ESC_NETWORK "network" /* network interface */ -#define ESC_PRINTER "printer" /* printer device */ -#define ESC_LOFI "lofi" /* lofi device */ - -/* - * EC_DEV_BRANCH subclass definitions - supporting attributes (name/value pairs) - * are found in sys/sysevent/dev.h - */ - -/* device tree branch added */ -#define ESC_DEV_BRANCH_ADD "ESC_dev_branch_add" - -/* device tree branch removed */ -#define ESC_DEV_BRANCH_REMOVE "ESC_dev_branch_remove" - -/* FMA Fault and Error event protocol subclass */ -#define ESC_FM_ERROR "ESC_FM_error" -#define ESC_FM_ERROR_REPLAY "ESC_FM_error_replay" - -/* Service processor subclass definitions */ -#define ESC_PLATFORM_SP_RESET "ESC_platform_sp_reset" - -/* - * EC_ACPIEV subclass definitions - */ -#define EC_ACPIEV "EC_acpiev" -#define ESC_ACPIEV_ADD "ESC_acpiev_add" -#define ESC_ACPIEV_REMOVE "ESC_acpiev_remove" -#define ESC_ACPIEV_WARN "ESC_acpiev_warn" -#define ESC_ACPIEV_LOW "ESC_acpiev_low" -#define ESC_ACPIEV_STATE_CHANGE "ESC_acpiev_state_change" - -/* - * ZFS subclass definitions. supporting attributes (name/value paris) are found - * in sys/fs/zfs.h - */ -#define ESC_ZFS_RESILVER_START "ESC_ZFS_resilver_start" -#define ESC_ZFS_RESILVER_FINISH "ESC_ZFS_resilver_finish" -#define ESC_ZFS_VDEV_REMOVE "ESC_ZFS_vdev_remove" -#define ESC_ZFS_POOL_DESTROY "ESC_ZFS_pool_destroy" -#define ESC_ZFS_VDEV_CLEAR "ESC_ZFS_vdev_clear" -#define ESC_ZFS_VDEV_CHECK "ESC_ZFS_vdev_check" - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_SYSEVENT_EVENTDEFS_H */ diff --git a/zfs/lib/libsolcompat/include/sys/sysmacros.h b/zfs/lib/libsolcompat/include/sys/sysmacros.h deleted file mode 100644 index 302fc3563..000000000 --- a/zfs/lib/libsolcompat/include/sys/sysmacros.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_SYSMACROS_H -#define _SOL_SYS_SYSMACROS_H - -#include_next - -#define makedevice(maj,min) makedev(maj,min) - -/* common macros */ -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a, b) ((a) < (b) ? (b) : (a)) -#endif -#ifndef ABS -#define ABS(a) ((a) < 0 ? -(a) : (a)) -#endif - -/* - * Compatibility macros/typedefs needed for Solaris -> Linux port - */ -#define P2ALIGN(x, align) ((x) & -(align)) -#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1) -#define P2ROUNDUP(x, align) (-(-(x) & -(align))) -#define P2ROUNDUP_TYPED(x, align, type) \ - (-(-(type)(x) & -(type)(align))) -#define P2PHASE(x, align) ((x) & ((align) - 1)) -#define P2NPHASE(x, align) (-(x) & ((align) - 1)) -#define P2NPHASE_TYPED(x, align, type) \ - (-(type)(x) & ((type)(align) - 1)) -#define ISP2(x) (((x) & ((x) - 1)) == 0) -#define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0) - -/* - * Typed version of the P2* macros. These macros should be used to ensure - * that the result is correctly calculated based on the data type of (x), - * which is passed in as the last argument, regardless of the data - * type of the alignment. For example, if (x) is of type uint64_t, - * and we want to round it up to a page boundary using "PAGESIZE" as - * the alignment, we can do either - * P2ROUNDUP(x, (uint64_t)PAGESIZE) - * or - * P2ROUNDUP_TYPED(x, PAGESIZE, uint64_t) - */ -#define P2ALIGN_TYPED(x, align, type) \ - ((type)(x) & -(type)(align)) -#define P2PHASE_TYPED(x, align, type) \ - ((type)(x) & ((type)(align) - 1)) -#define P2NPHASE_TYPED(x, align, type) \ - (-(type)(x) & ((type)(align) - 1)) -#define P2ROUNDUP_TYPED(x, align, type) \ - (-(-(type)(x) & -(type)(align))) -#define P2END_TYPED(x, align, type) \ - (-(~(type)(x) & -(type)(align))) -#define P2PHASEUP_TYPED(x, align, phase, type) \ - ((type)(phase) - (((type)(phase) - (type)(x)) & -(type)(align))) -#define P2CROSS_TYPED(x, y, align, type) \ - (((type)(x) ^ (type)(y)) > (type)(align) - 1) -#define P2SAMEHIGHBIT_TYPED(x, y, type) \ - (((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y))) - -#if defined(_KERNEL) && !defined(_KMEMUSER) && !defined(offsetof) - -/* avoid any possibility of clashing with version */ - -#define offsetof(s, m) ((size_t)(&(((s *)0)->m))) -#endif - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/time.h b/zfs/lib/libsolcompat/include/sys/time.h deleted file mode 100644 index 24d52e8cf..000000000 --- a/zfs/lib/libsolcompat/include/sys/time.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_TIME_H -#define _SOL_SYS_TIME_H - -#include_next - -#include -#include -#include -#include - -typedef longlong_t hrtime_t; -typedef struct timespec timestruc_t; - -static inline hrtime_t gethrtime(void) { - struct timespec ts; - - if(clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { - fprintf(stderr, "Error: clock_gettime(CLOCK_MONOTONIC) failed\n"); - fprintf(stderr, "Make sure you are are running kernel 2.6.x and have glibc 2.3.3 or newer installed\n"); - fprintf(stderr, "Aborting...\n"); - abort(); - } - - return (((u_int64_t)ts.tv_sec) * NANOSEC) + ts.tv_nsec; -} - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/trap.h b/zfs/lib/libsolcompat/include/sys/trap.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/types.h b/zfs/lib/libsolcompat/include/sys/types.h deleted file mode 100644 index 0c912effc..000000000 --- a/zfs/lib/libsolcompat/include/sys/types.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_SYS_TYPES_H -#define _SOL_SYS_TYPES_H - -#include -#include -#include_next -#include /* for NBBY */ -#include - -typedef longlong_t offset_t; -typedef u_longlong_t u_offset_t; -typedef u_longlong_t len_t; -typedef longlong_t diskaddr_t; - -typedef short pri_t; - -typedef int zoneid_t; -typedef int projid_t; - -typedef int major_t; -typedef int minor_t; - -typedef ushort_t o_mode_t; /* old file attribute type */ - -/* - * Definitions remaining from previous partial support for 64-bit file - * offsets. This partial support for devices greater than 2gb requires - * compiler support for long long. - */ -#ifdef _LONG_LONG_LTOH -typedef union { - offset_t _f; /* Full 64 bit offset value */ - struct { - int32_t _l; /* lower 32 bits of offset value */ - int32_t _u; /* upper 32 bits of offset value */ - } _p; -} lloff_t; -#endif - -#ifdef _LONG_LONG_HTOL -typedef union { - offset_t _f; /* Full 64 bit offset value */ - struct { - int32_t _u; /* upper 32 bits of offset value */ - int32_t _l; /* lower 32 bits of offset value */ - } _p; -} lloff_t; -#endif - -#include - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/types32.h b/zfs/lib/libsolcompat/include/sys/types32.h deleted file mode 100644 index 6df64e713..000000000 --- a/zfs/lib/libsolcompat/include/sys/types32.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_TYPES32_H -#define _SYS_TYPES32_H - - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Interoperability types for programs. Used for: - * - * Crossing between 32-bit and 64-bit domains. - * - * On disk data formats such as filesystem meta data - * and disk label. - * - * Note: Applications should never include this - * header file. - */ -typedef uint32_t caddr32_t; -typedef int32_t daddr32_t; -typedef int32_t off32_t; -typedef uint32_t ino32_t; -typedef int32_t blkcnt32_t; -typedef uint32_t fsblkcnt32_t; -typedef uint32_t fsfilcnt32_t; -typedef int32_t id32_t; -typedef uint32_t major32_t; -typedef uint32_t minor32_t; -typedef int32_t key32_t; -typedef uint32_t mode32_t; -typedef uint32_t uid32_t; -typedef uint32_t gid32_t; -typedef uint32_t nlink32_t; -typedef uint32_t dev32_t; -typedef int32_t pid32_t; -typedef uint32_t size32_t; -typedef int32_t ssize32_t; -typedef int32_t time32_t; -typedef int32_t clock32_t; - -struct timeval32 { - time32_t tv_sec; /* seconds */ - int32_t tv_usec; /* and microseconds */ -}; - -typedef struct timespec32 { - time32_t tv_sec; /* seconds */ - int32_t tv_nsec; /* and nanoseconds */ -} timespec32_t; - -typedef struct timespec32 timestruc32_t; - -typedef struct itimerspec32 { - struct timespec32 it_interval; - struct timespec32 it_value; -} itimerspec32_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_TYPES32_H */ diff --git a/zfs/lib/libsolcompat/include/sys/uio.h b/zfs/lib/libsolcompat/include/sys/uio.h deleted file mode 100644 index ccfc8b777..000000000 --- a/zfs/lib/libsolcompat/include/sys/uio.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#ifndef _SOL_SYS_UIO_H -#define _SOL_SYS_UIO_H - -/* struct iovec is defined in glibc's sys/uio.h */ -#include_next - -typedef enum uio_rw { UIO_READ, UIO_WRITE } uio_rw_t; - -#define UIO_SYSSPACE 1 - -#endif /* _SYS_UIO_H */ diff --git a/zfs/lib/libsolcompat/include/sys/utsname.h b/zfs/lib/libsolcompat/include/sys/utsname.h deleted file mode 100644 index f58b82c34..000000000 --- a/zfs/lib/libsolcompat/include/sys/utsname.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_UTSNAME_H -#define _SOL_UTSNAME_H - -#include_next - -struct utsname utsname; - -#endif - diff --git a/zfs/lib/libsolcompat/include/sys/uuid.h b/zfs/lib/libsolcompat/include/sys/uuid.h deleted file mode 100644 index cbf0a77ea..000000000 --- a/zfs/lib/libsolcompat/include/sys/uuid.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_UUID_H -#define _SYS_UUID_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The copyright in this file is taken from the original Leach - * & Salz UUID specification, from which this implementation - * is derived. - */ - -/* - * Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. - * Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & - * Digital Equipment Corporation, Maynard, Mass. Copyright (c) 1998 - * Microsoft. To anyone who acknowledges that this file is provided - * "AS IS" without any express or implied warranty: permission to use, - * copy, modify, and distribute this file for any purpose is hereby - * granted without fee, provided that the above copyright notices and - * this notice appears in all source code copies, and that none of the - * names of Open Software Foundation, Inc., Hewlett-Packard Company, - * or Digital Equipment Corporation be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. Neither Open Software - * Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital - * Equipment Corporation makes any representations about the - * suitability of this software for any purpose. - */ - -#include -#include - -typedef struct { - uint8_t nodeID[6]; -} uuid_node_t; - -/* - * The uuid type used throughout when referencing uuids themselves - */ -struct uuid { - uint32_t time_low; - uint16_t time_mid; - uint16_t time_hi_and_version; - uint8_t clock_seq_hi_and_reserved; - uint8_t clock_seq_low; - uint8_t node_addr[6]; -}; - -#define UUID_LEN 16 - -#define UUID_PRINTABLE_STRING_LENGTH 37 - -typedef uchar_t uuid_t[UUID_LEN]; - -/* - * Convert a uuid to/from little-endian format - */ -#define UUID_LE_CONVERT(dest, src) \ -{ \ - (dest) = (src); \ - (dest).time_low = LE_32((dest).time_low); \ - (dest).time_mid = LE_16((dest).time_mid); \ - (dest).time_hi_and_version = LE_16((dest).time_hi_and_version); \ -} - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_UUID_H */ diff --git a/zfs/lib/libsolcompat/include/sys/va_list.h b/zfs/lib/libsolcompat/include/sys/va_list.h deleted file mode 100644 index f7c5a92cf..000000000 --- a/zfs/lib/libsolcompat/include/sys/va_list.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_VA_LIST_H -#define _SYS_VA_LIST_H - -#include - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/varargs.h b/zfs/lib/libsolcompat/include/sys/varargs.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/sys/vmem.h b/zfs/lib/libsolcompat/include/sys/vmem.h deleted file mode 100644 index fb8ef4043..000000000 --- a/zfs/lib/libsolcompat/include/sys/vmem.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_VMEM_H -#define _SYS_VMEM_H - -/* vmem_t is necessary in the declaration but it's not used in the dummy implementation */ -struct vmem; -typedef struct vmem vmem_t; - -#endif diff --git a/zfs/lib/libsolcompat/include/sys/vtoc.h b/zfs/lib/libsolcompat/include/sys/vtoc.h deleted file mode 100644 index 3dd25eeb1..000000000 --- a/zfs/lib/libsolcompat/include/sys/vtoc.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1997-1998,2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#ifndef _SYS_VTOC_H -#define _SYS_VTOC_H - - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Note: the VTOC is not implemented fully, nor in the manner - * that AT&T implements it. AT&T puts the vtoc structure - * into a sector, usually the second sector (pdsector is first). - * - * Sun incorporates the tag, flag, version, and volume vtoc fields into - * its Disk Label, which already has some vtoc-equivalent fields. - * Upon reading the vtoc with read_vtoc(), the following exceptions - * occur: - * v_bootinfo [all] returned as zero - * v_sanity returned as VTOC_SANE - * if Disk Label was sane - * v_sectorsz returned as 512 - * v_reserved [all] retunred as zero - * timestamp [all] returned as zero - * - * See dklabel.h, read_vtoc(), and write_vtoc(). - */ - -#define V_NUMPAR NDKMAP /* The number of partitions */ - /* (from dkio.h) */ - -#define VTOC_SANE 0x600DDEEE /* Indicates a sane VTOC */ -#define V_VERSION 0x01 /* layout version number */ - -/* - * Partition identification tags - */ -#define V_UNASSIGNED 0x00 /* unassigned partition */ -#define V_BOOT 0x01 /* Boot partition */ -#define V_ROOT 0x02 /* Root filesystem */ -#define V_SWAP 0x03 /* Swap filesystem */ -#define V_USR 0x04 /* Usr filesystem */ -#define V_BACKUP 0x05 /* full disk */ -#define V_STAND 0x06 /* Stand partition */ -#define V_VAR 0x07 /* Var partition */ -#define V_HOME 0x08 /* Home partition */ -#define V_ALTSCTR 0x09 /* Alternate sector partition */ -#define V_CACHE 0x0a /* Cache (cachefs) partition */ -#define V_RESERVED 0x0b /* SMI reserved data */ - -/* - * Partition permission flags - */ -#define V_UNMNT 0x01 /* Unmountable partition */ -#define V_RONLY 0x10 /* Read only */ - -/* - * error codes for reading & writing vtoc - */ -#define VT_ERROR (-2) /* errno supplies specific error */ -#define VT_EIO (-3) /* I/O error accessing vtoc */ -#define VT_EINVAL (-4) /* illegal value in vtoc or request */ -#define VT_ENOTSUP (-5) /* VTOC op. not supported */ - -struct partition { - ushort_t p_tag; /* ID tag of partition */ - ushort_t p_flag; /* permision flags */ - daddr_t p_start; /* start sector no of partition */ - long p_size; /* # of blocks in partition */ -}; - -struct vtoc { - unsigned long v_bootinfo[3]; /* info needed by mboot (unsupported) */ - unsigned long v_sanity; /* to verify vtoc sanity */ - unsigned long v_version; /* layout version */ - char v_volume[LEN_DKL_VVOL]; /* volume name */ - ushort_t v_sectorsz; /* sector size in bytes */ - ushort_t v_nparts; /* number of partitions */ - unsigned long v_reserved[10]; /* free space */ - struct partition v_part[V_NUMPAR]; /* partition headers */ - time_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */ - char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ -}; - -#if defined(_SYSCALL32) -struct partition32 { - uint16_t p_tag; /* ID tag of partition */ - uint16_t p_flag; /* permision flags */ - daddr32_t p_start; /* start sector no of partition */ - int32_t p_size; /* # of blocks in partition */ -}; - -struct vtoc32 { - uint32_t v_bootinfo[3]; /* info needed by mboot (unsupported) */ - uint32_t v_sanity; /* to verify vtoc sanity */ - uint32_t v_version; /* layout version */ - char v_volume[LEN_DKL_VVOL]; /* volume name */ - uint16_t v_sectorsz; /* sector size in bytes */ - uint16_t v_nparts; /* number of partitions */ - uint32_t v_reserved[10]; /* free space */ - struct partition32 v_part[V_NUMPAR]; /* partition headers */ - time32_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */ - char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ -}; - -#define vtoc32tovtoc(v32, v) \ - { \ - int i; \ - v.v_bootinfo[0] = v32.v_bootinfo[0]; \ - v.v_bootinfo[1] = v32.v_bootinfo[1]; \ - v.v_bootinfo[2] = v32.v_bootinfo[2]; \ - v.v_sanity = v32.v_sanity; \ - v.v_version = v32.v_version; \ - bcopy(v32.v_volume, v.v_volume, LEN_DKL_VVOL); \ - v.v_sectorsz = v32.v_sectorsz; \ - v.v_nparts = v32.v_nparts; \ - v.v_version = v32.v_version; \ - for (i = 0; i < 10; i++) \ - v.v_reserved[i] = v32.v_reserved[i]; \ - for (i = 0; i < V_NUMPAR; i++) { \ - v.v_part[i].p_tag = (ushort_t)v32.v_part[i].p_tag; \ - v.v_part[i].p_flag = (ushort_t)v32.v_part[i].p_flag; \ - v.v_part[i].p_start = (daddr_t)v32.v_part[i].p_start; \ - v.v_part[i].p_size = (long)v32.v_part[i].p_size; \ - } \ - for (i = 0; i < V_NUMPAR; i++) \ - v.timestamp[i] = (time_t)v32.timestamp[i]; \ - bcopy(v32.v_asciilabel, v.v_asciilabel, LEN_DKL_ASCII); \ - } - -#define vtoctovtoc32(v, v32) \ - { \ - int i; \ - v32.v_bootinfo[0] = v.v_bootinfo[0]; \ - v32.v_bootinfo[1] = v.v_bootinfo[1]; \ - v32.v_bootinfo[2] = v.v_bootinfo[2]; \ - v32.v_sanity = v.v_sanity; \ - v32.v_version = v.v_version; \ - bcopy(v.v_volume, v32.v_volume, LEN_DKL_VVOL); \ - v32.v_sectorsz = v.v_sectorsz; \ - v32.v_nparts = v.v_nparts; \ - v32.v_version = v.v_version; \ - for (i = 0; i < 10; i++) \ - v32.v_reserved[i] = v.v_reserved[i]; \ - for (i = 0; i < V_NUMPAR; i++) { \ - v32.v_part[i].p_tag = (ushort_t)v.v_part[i].p_tag; \ - v32.v_part[i].p_flag = (ushort_t)v.v_part[i].p_flag; \ - v32.v_part[i].p_start = (daddr32_t)v.v_part[i].p_start; \ - v32.v_part[i].p_size = (int32_t)v.v_part[i].p_size; \ - } \ - for (i = 0; i < V_NUMPAR; i++) { \ - if (v.timestamp[i] > TIME32_MAX) \ - v32.timestamp[i] = TIME32_MAX; \ - else \ - v32.timestamp[i] = (time32_t)v.timestamp[i]; \ - } \ - bcopy(v.v_asciilabel, v32.v_asciilabel, LEN_DKL_ASCII); \ - } - -#endif /* _SYSCALL32 */ - -/* - * These defines are the mode parameter for the checksum routines. - */ -#define CK_CHECKSUM 0 /* check checksum */ -#define CK_MAKESUM 1 /* generate checksum */ - -#if defined(__STDC__) - -extern int read_vtoc(int, struct vtoc *); -extern int write_vtoc(int, struct vtoc *); - -#else - -extern int read_vtoc(); -extern int write_vtoc(); - -#endif /* __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_VTOC_H */ diff --git a/zfs/lib/libsolcompat/include/sys/zone.h b/zfs/lib/libsolcompat/include/sys/zone.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/tsol/label.h b/zfs/lib/libsolcompat/include/tsol/label.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/include/ucred.h b/zfs/lib/libsolcompat/include/ucred.h deleted file mode 100644 index e1c3342fb..000000000 --- a/zfs/lib/libsolcompat/include/ucred.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SOL_UCRED_H -#define _SOL_UCRED_H - -typedef int ucred_t; - -#endif diff --git a/zfs/lib/libsolcompat/include/zone.h b/zfs/lib/libsolcompat/include/zone.h deleted file mode 100644 index 3c18b6105..000000000 --- a/zfs/lib/libsolcompat/include/zone.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _ZONE_H -#define _ZONE_H - - - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define GLOBAL_ZONEID 0 -#define GLOBAL_ZONEID_NAME "global" - -/* - * Functions for mapping between id and name for active zones. - */ -extern zoneid_t getzoneid(void); -extern zoneid_t getzoneidbyname(const char *); -extern ssize_t getzonenamebyid(zoneid_t, char *, size_t); - -#if 0 - -/* - * NOTE - * - * The remaining contents of this file are private to the implementation - * of Solaris and are subject to change at any time without notice, - * Applications using these interfaces may fail to run on future releases. - */ - -extern int zonept(int, zoneid_t); -extern int zone_get_id(const char *, zoneid_t *); - -/* System call API */ -extern zoneid_t zone_create(const char *, const char *, - const struct priv_set *, const char *, size_t, const char *, size_t, int *, - int, int, const bslabel_t *, int); -extern int zone_boot(zoneid_t); -extern int zone_destroy(zoneid_t); -extern ssize_t zone_getattr(zoneid_t, int, void *, size_t); -extern int zone_setattr(zoneid_t, int, void *, size_t); -extern int zone_enter(zoneid_t); -extern int zone_list(zoneid_t *, uint_t *); -extern int zone_shutdown(zoneid_t); -extern int zone_version(int *); -extern int zone_add_datalink(zoneid_t, char *); -extern int zone_remove_datalink(zoneid_t, char *); -extern int zone_check_datalink(zoneid_t *, char *); -extern int zone_list_datalink(zoneid_t, int *, char *); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _ZONE_H */ diff --git a/zfs/lib/libsolcompat/sparc64/atomic.S b/zfs/lib/libsolcompat/sparc64/atomic.S deleted file mode 100644 index b880cf024..000000000 --- a/zfs/lib/libsolcompat/sparc64/atomic.S +++ /dev/null @@ -1,813 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - .ident "%Z%%M% %I% %E% SMI" - - .file "%M%" - -#define _ASM -#include - -#if defined(_KERNEL) - /* - * Legacy kernel interfaces; they will go away (eventually). - */ - ANSI_PRAGMA_WEAK2(cas8,atomic_cas_8,function) - ANSI_PRAGMA_WEAK2(cas32,atomic_cas_32,function) - ANSI_PRAGMA_WEAK2(cas64,atomic_cas_64,function) - ANSI_PRAGMA_WEAK2(caslong,atomic_cas_ulong,function) - ANSI_PRAGMA_WEAK2(casptr,atomic_cas_ptr,function) - ANSI_PRAGMA_WEAK2(atomic_and_long,atomic_and_ulong,function) - ANSI_PRAGMA_WEAK2(atomic_or_long,atomic_or_ulong,function) - ANSI_PRAGMA_WEAK2(swapl,atomic_swap_32,function) -#else - /* - * Include the definitions for the libc weak aliases. - */ -#include "../atomic_asm_weak.h" -#endif - - /* - * NOTE: If atomic_inc_8 and atomic_inc_8_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_inc_8_nv. - */ - ENTRY(atomic_inc_8) - ALTENTRY(atomic_inc_8_nv) - ALTENTRY(atomic_inc_uchar) - ALTENTRY(atomic_inc_uchar_nv) - ba add_8 - add %g0, 1, %o1 - SET_SIZE(atomic_inc_uchar_nv) - SET_SIZE(atomic_inc_uchar) - SET_SIZE(atomic_inc_8_nv) - SET_SIZE(atomic_inc_8) - - /* - * NOTE: If atomic_dec_8 and atomic_dec_8_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_dec_8_nv. - */ - ENTRY(atomic_dec_8) - ALTENTRY(atomic_dec_8_nv) - ALTENTRY(atomic_dec_uchar) - ALTENTRY(atomic_dec_uchar_nv) - ba add_8 - sub %g0, 1, %o1 - SET_SIZE(atomic_dec_uchar_nv) - SET_SIZE(atomic_dec_uchar) - SET_SIZE(atomic_dec_8_nv) - SET_SIZE(atomic_dec_8) - - /* - * NOTE: If atomic_add_8 and atomic_add_8_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_add_8_nv. - */ - ENTRY(atomic_add_8) - ALTENTRY(atomic_add_8_nv) - ALTENTRY(atomic_add_char) - ALTENTRY(atomic_add_char_nv) -add_8: - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single byte value - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o2 ! read old value -1: - add %o2, %o1, %o5 ! add value to the old value - and %o5, %o3, %o5 ! clear other bits - andn %o2, %o3, %o4 ! clear target bits - or %o4, %o5, %o5 ! insert the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - add %o2, %o1, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_add_char_nv) - SET_SIZE(atomic_add_char) - SET_SIZE(atomic_add_8_nv) - SET_SIZE(atomic_add_8) - - /* - * NOTE: If atomic_inc_16 and atomic_inc_16_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_inc_16_nv. - */ - ENTRY(atomic_inc_16) - ALTENTRY(atomic_inc_16_nv) - ALTENTRY(atomic_inc_ushort) - ALTENTRY(atomic_inc_ushort_nv) - ba add_16 - add %g0, 1, %o1 - SET_SIZE(atomic_inc_ushort_nv) - SET_SIZE(atomic_inc_ushort) - SET_SIZE(atomic_inc_16_nv) - SET_SIZE(atomic_inc_16) - - /* - * NOTE: If atomic_dec_16 and atomic_dec_16_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_dec_16_nv. - */ - ENTRY(atomic_dec_16) - ALTENTRY(atomic_dec_16_nv) - ALTENTRY(atomic_dec_ushort) - ALTENTRY(atomic_dec_ushort_nv) - ba add_16 - sub %g0, 1, %o1 - SET_SIZE(atomic_dec_ushort_nv) - SET_SIZE(atomic_dec_ushort) - SET_SIZE(atomic_dec_16_nv) - SET_SIZE(atomic_dec_16) - - /* - * NOTE: If atomic_add_16 and atomic_add_16_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_add_16_nv. - */ - ENTRY(atomic_add_16) - ALTENTRY(atomic_add_16_nv) - ALTENTRY(atomic_add_short) - ALTENTRY(atomic_add_short_nv) -add_16: - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single short value - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o2 ! read old value -1: - add %o1, %o2, %o5 ! add value to the old value - and %o5, %o3, %o5 ! clear other bits - andn %o2, %o3, %o4 ! clear target bits - or %o4, %o5, %o5 ! insert the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - add %o1, %o2, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_add_short_nv) - SET_SIZE(atomic_add_short) - SET_SIZE(atomic_add_16_nv) - SET_SIZE(atomic_add_16) - - /* - * NOTE: If atomic_inc_32 and atomic_inc_32_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_inc_32_nv. - */ - ENTRY(atomic_inc_32) - ALTENTRY(atomic_inc_32_nv) - ALTENTRY(atomic_inc_uint) - ALTENTRY(atomic_inc_uint_nv) - ALTENTRY(atomic_inc_ulong) - ALTENTRY(atomic_inc_ulong_nv) - ba add_32 - add %g0, 1, %o1 - SET_SIZE(atomic_inc_ulong_nv) - SET_SIZE(atomic_inc_ulong) - SET_SIZE(atomic_inc_uint_nv) - SET_SIZE(atomic_inc_uint) - SET_SIZE(atomic_inc_32_nv) - SET_SIZE(atomic_inc_32) - - /* - * NOTE: If atomic_dec_32 and atomic_dec_32_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_dec_32_nv. - */ - ENTRY(atomic_dec_32) - ALTENTRY(atomic_dec_32_nv) - ALTENTRY(atomic_dec_uint) - ALTENTRY(atomic_dec_uint_nv) - ALTENTRY(atomic_dec_ulong) - ALTENTRY(atomic_dec_ulong_nv) - ba add_32 - sub %g0, 1, %o1 - SET_SIZE(atomic_dec_ulong_nv) - SET_SIZE(atomic_dec_ulong) - SET_SIZE(atomic_dec_uint_nv) - SET_SIZE(atomic_dec_uint) - SET_SIZE(atomic_dec_32_nv) - SET_SIZE(atomic_dec_32) - - /* - * NOTE: If atomic_add_32 and atomic_add_32_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_add_32_nv. - */ - ENTRY(atomic_add_32) - ALTENTRY(atomic_add_32_nv) - ALTENTRY(atomic_add_int) - ALTENTRY(atomic_add_int_nv) - ALTENTRY(atomic_add_ptr) - ALTENTRY(atomic_add_ptr_nv) - ALTENTRY(atomic_add_long) - ALTENTRY(atomic_add_long_nv) -add_32: - ld [%o0], %o2 -1: - add %o2, %o1, %o3 - cas [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %icc, 1b - mov %o3, %o2 - retl - add %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_add_long_nv) - SET_SIZE(atomic_add_long) - SET_SIZE(atomic_add_ptr_nv) - SET_SIZE(atomic_add_ptr) - SET_SIZE(atomic_add_int_nv) - SET_SIZE(atomic_add_int) - SET_SIZE(atomic_add_32_nv) - SET_SIZE(atomic_add_32) - - /* - * NOTE: If atomic_inc_64 and atomic_inc_64_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_inc_64_nv. - */ - ENTRY(atomic_inc_64) - ALTENTRY(atomic_inc_64_nv) - ba add_64 - add %g0, 1, %o1 - SET_SIZE(atomic_inc_64_nv) - SET_SIZE(atomic_inc_64) - - /* - * NOTE: If atomic_dec_64 and atomic_dec_64_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_dec_64_nv. - */ - ENTRY(atomic_dec_64) - ALTENTRY(atomic_dec_64_nv) - ba add_64 - sub %g0, 1, %o1 - SET_SIZE(atomic_dec_64_nv) - SET_SIZE(atomic_dec_64) - - /* - * NOTE: If atomic_add_64 and atomic_add_64_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_add_64_nv. - */ - ENTRY(atomic_add_64) - ALTENTRY(atomic_add_64_nv) - sllx %o1, 32, %o1 ! upper 32 in %o1, lower in %o2 - srl %o2, 0, %o2 - add %o1, %o2, %o1 ! convert 2 32-bit args into 1 64-bit -add_64: - ldx [%o0], %o2 -1: - add %o2, %o1, %o3 - casx [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %xcc, 1b - mov %o3, %o2 - add %o2, %o1, %o1 ! return lower 32-bits in %o1 - retl - srlx %o1, 32, %o0 ! return upper 32-bits in %o0 - SET_SIZE(atomic_add_64_nv) - SET_SIZE(atomic_add_64) - - /* - * NOTE: If atomic_or_8 and atomic_or_8_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_or_8_nv. - */ - ENTRY(atomic_or_8) - ALTENTRY(atomic_or_8_nv) - ALTENTRY(atomic_or_uchar) - ALTENTRY(atomic_or_uchar_nv) - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single byte value - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o2 ! read old value -1: - or %o2, %o1, %o5 ! or in the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - or %o2, %o1, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_or_uchar_nv) - SET_SIZE(atomic_or_uchar) - SET_SIZE(atomic_or_8_nv) - SET_SIZE(atomic_or_8) - - /* - * NOTE: If atomic_or_16 and atomic_or_16_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_or_16_nv. - */ - ENTRY(atomic_or_16) - ALTENTRY(atomic_or_16_nv) - ALTENTRY(atomic_or_ushort) - ALTENTRY(atomic_or_ushort_nv) - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single short value - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o2 ! read old value -1: - or %o2, %o1, %o5 ! or in the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - or %o2, %o1, %o5 ! or in the new value - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_or_ushort_nv) - SET_SIZE(atomic_or_ushort) - SET_SIZE(atomic_or_16_nv) - SET_SIZE(atomic_or_16) - - /* - * NOTE: If atomic_or_32 and atomic_or_32_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_or_32_nv. - */ - ENTRY(atomic_or_32) - ALTENTRY(atomic_or_32_nv) - ALTENTRY(atomic_or_uint) - ALTENTRY(atomic_or_uint_nv) - ALTENTRY(atomic_or_ulong) - ALTENTRY(atomic_or_ulong_nv) - ld [%o0], %o2 -1: - or %o2, %o1, %o3 - cas [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %icc, 1b - mov %o3, %o2 - retl - or %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_or_ulong_nv) - SET_SIZE(atomic_or_ulong) - SET_SIZE(atomic_or_uint_nv) - SET_SIZE(atomic_or_uint) - SET_SIZE(atomic_or_32_nv) - SET_SIZE(atomic_or_32) - - /* - * NOTE: If atomic_or_64 and atomic_or_64_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_or_64_nv. - */ - ENTRY(atomic_or_64) - ALTENTRY(atomic_or_64_nv) - sllx %o1, 32, %o1 ! upper 32 in %o1, lower in %o2 - srl %o2, 0, %o2 - add %o1, %o2, %o1 ! convert 2 32-bit args into 1 64-bit - ldx [%o0], %o2 -1: - or %o2, %o1, %o3 - casx [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %xcc, 1b - mov %o3, %o2 - or %o2, %o1, %o1 ! return lower 32-bits in %o1 - retl - srlx %o1, 32, %o0 ! return upper 32-bits in %o0 - SET_SIZE(atomic_or_64_nv) - SET_SIZE(atomic_or_64) - - /* - * NOTE: If atomic_and_8 and atomic_and_8_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_and_8_nv. - */ - ENTRY(atomic_and_8) - ALTENTRY(atomic_and_8_nv) - ALTENTRY(atomic_and_uchar) - ALTENTRY(atomic_and_uchar_nv) - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - orn %o1, %o3, %o1 ! all ones in other bytes - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o2 ! read old value -1: - and %o2, %o1, %o5 ! and in the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - and %o2, %o1, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_and_uchar_nv) - SET_SIZE(atomic_and_uchar) - SET_SIZE(atomic_and_8_nv) - SET_SIZE(atomic_and_8) - - /* - * NOTE: If atomic_and_16 and atomic_and_16_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_and_16_nv. - */ - ENTRY(atomic_and_16) - ALTENTRY(atomic_and_16_nv) - ALTENTRY(atomic_and_ushort) - ALTENTRY(atomic_and_ushort_nv) - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - orn %o1, %o3, %o1 ! all ones in the other half - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o2 ! read old value -1: - and %o2, %o1, %o5 ! and in the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - and %o2, %o1, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_and_ushort_nv) - SET_SIZE(atomic_and_ushort) - SET_SIZE(atomic_and_16_nv) - SET_SIZE(atomic_and_16) - - /* - * NOTE: If atomic_and_32 and atomic_and_32_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_and_32_nv. - */ - ENTRY(atomic_and_32) - ALTENTRY(atomic_and_32_nv) - ALTENTRY(atomic_and_uint) - ALTENTRY(atomic_and_uint_nv) - ALTENTRY(atomic_and_ulong) - ALTENTRY(atomic_and_ulong_nv) - ld [%o0], %o2 -1: - and %o2, %o1, %o3 - cas [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %icc, 1b - mov %o3, %o2 - retl - and %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_and_ulong_nv) - SET_SIZE(atomic_and_ulong) - SET_SIZE(atomic_and_uint_nv) - SET_SIZE(atomic_and_uint) - SET_SIZE(atomic_and_32_nv) - SET_SIZE(atomic_and_32) - - /* - * NOTE: If atomic_and_64 and atomic_and_64_nv are ever - * separated, you need to also edit the libc sparc platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_and_64_nv. - */ - ENTRY(atomic_and_64) - ALTENTRY(atomic_and_64_nv) - sllx %o1, 32, %o1 ! upper 32 in %o1, lower in %o2 - srl %o2, 0, %o2 - add %o1, %o2, %o1 ! convert 2 32-bit args into 1 64-bit - ldx [%o0], %o2 -1: - and %o2, %o1, %o3 - casx [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %xcc, 1b - mov %o3, %o2 - and %o2, %o1, %o1 ! return lower 32-bits in %o1 - retl - srlx %o1, 32, %o0 ! return upper 32-bits in %o0 - SET_SIZE(atomic_and_64_nv) - SET_SIZE(atomic_and_64) - - ENTRY(atomic_cas_8) - ALTENTRY(atomic_cas_uchar) - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single byte value - sll %o2, %g1, %o2 ! %o2 = shifted to bit offset - and %o2, %o3, %o2 ! %o2 = single byte value - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o4 ! read old value -1: - andn %o4, %o3, %o4 ! clear target bits - or %o4, %o2, %o5 ! insert the new value - or %o4, %o1, %o4 ! insert the comparison value - cas [%o0], %o4, %o5 - cmp %o4, %o5 ! did we succeed? - be,pt %icc, 2f - and %o5, %o3, %o4 ! isolate the old value - cmp %o1, %o4 ! should we have succeeded? - be,a,pt %icc, 1b ! yes, try again - mov %o5, %o4 ! %o4 = old value -2: - retl - srl %o4, %g1, %o0 ! %o0 = old value - SET_SIZE(atomic_cas_uchar) - SET_SIZE(atomic_cas_8) - - ENTRY(atomic_cas_16) - ALTENTRY(atomic_cas_ushort) - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single short value - sll %o2, %g1, %o2 ! %o2 = shifted to bit offset - and %o2, %o3, %o2 ! %o2 = single short value - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o4 ! read old value -1: - andn %o4, %o3, %o4 ! clear target bits - or %o4, %o2, %o5 ! insert the new value - or %o4, %o1, %o4 ! insert the comparison value - cas [%o0], %o4, %o5 - cmp %o4, %o5 ! did we succeed? - be,pt %icc, 2f - and %o5, %o3, %o4 ! isolate the old value - cmp %o1, %o4 ! should we have succeeded? - be,a,pt %icc, 1b ! yes, try again - mov %o5, %o4 ! %o4 = old value -2: - retl - srl %o4, %g1, %o0 ! %o0 = old value - SET_SIZE(atomic_cas_ushort) - SET_SIZE(atomic_cas_16) - - ENTRY(atomic_cas_32) - ALTENTRY(atomic_cas_uint) - ALTENTRY(atomic_cas_ptr) - ALTENTRY(atomic_cas_ulong) - cas [%o0], %o1, %o2 - retl - mov %o2, %o0 - SET_SIZE(atomic_cas_ulong) - SET_SIZE(atomic_cas_ptr) - SET_SIZE(atomic_cas_uint) - SET_SIZE(atomic_cas_32) - - ENTRY(atomic_cas_64) - sllx %o1, 32, %o1 ! cmp's upper 32 in %o1, lower in %o2 - srl %o2, 0, %o2 ! convert 2 32-bit args into 1 64-bit - add %o1, %o2, %o1 - sllx %o3, 32, %o2 ! newval upper 32 in %o3, lower in %o4 - srl %o4, 0, %o4 ! setup %o2 to have newval - add %o2, %o4, %o2 - casx [%o0], %o1, %o2 - srl %o2, 0, %o1 ! return lower 32-bits in %o1 - retl - srlx %o2, 32, %o0 ! return upper 32-bits in %o0 - SET_SIZE(atomic_cas_64) - - ENTRY(atomic_swap_8) - ALTENTRY(atomic_swap_uchar) - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single byte value - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o2 ! read old value -1: - andn %o2, %o3, %o5 ! clear target bits - or %o5, %o1, %o5 ! insert the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = old value - SET_SIZE(atomic_swap_uchar) - SET_SIZE(atomic_swap_8) - - ENTRY(atomic_swap_16) - ALTENTRY(atomic_swap_ushort) - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single short value - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o2 ! read old value -1: - andn %o2, %o3, %o5 ! clear target bits - or %o5, %o1, %o5 ! insert the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = old value - SET_SIZE(atomic_swap_ushort) - SET_SIZE(atomic_swap_16) - - ENTRY(atomic_swap_32) - ALTENTRY(atomic_swap_uint) - ALTENTRY(atomic_swap_ptr) - ALTENTRY(atomic_swap_ulong) - ld [%o0], %o2 -1: - mov %o1, %o3 - cas [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %icc, 1b - mov %o3, %o2 - retl - mov %o3, %o0 - SET_SIZE(atomic_swap_ulong) - SET_SIZE(atomic_swap_ptr) - SET_SIZE(atomic_swap_uint) - SET_SIZE(atomic_swap_32) - - ENTRY(atomic_swap_64) - sllx %o1, 32, %o1 ! upper 32 in %o1, lower in %o2 - srl %o2, 0, %o2 - add %o1, %o2, %o1 ! convert 2 32-bit args into 1 64-bit - ldx [%o0], %o2 -1: - mov %o1, %o3 - casx [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %xcc, 1b - mov %o3, %o2 - srl %o3, 0, %o1 ! return lower 32-bits in %o1 - retl - srlx %o3, 32, %o0 ! return upper 32-bits in %o0 - SET_SIZE(atomic_swap_64) - -/* these are not used by ZFS - ENTRY(atomic_set_long_excl) - mov 1, %o3 - slln %o3, %o1, %o3 - ldn [%o0], %o2 -1: - andcc %o2, %o3, %g0 ! test if the bit is set - bnz,a,pn %ncc, 2f ! if so, then fail out - mov -1, %o0 - or %o2, %o3, %o4 ! set the bit, and try to commit it - casn [%o0], %o2, %o4 - cmp %o2, %o4 - bne,a,pn %ncc, 1b ! failed to commit, try again - mov %o4, %o2 - mov %g0, %o0 -2: - retl - nop - SET_SIZE(atomic_set_long_excl) - - ENTRY(atomic_clear_long_excl) - mov 1, %o3 - slln %o3, %o1, %o3 - ldn [%o0], %o2 -1: - andncc %o3, %o2, %g0 ! test if the bit is clear - bnz,a,pn %ncc, 2f ! if so, then fail out - mov -1, %o0 - andn %o2, %o3, %o4 ! clear the bit, and try to commit it - casn [%o0], %o2, %o4 - cmp %o2, %o4 - bne,a,pn %ncc, 1b ! failed to commit, try again - mov %o4, %o2 - mov %g0, %o0 -2: - retl - nop - SET_SIZE(atomic_clear_long_excl) -*/ -#if !defined(_KERNEL) - - /* - * Spitfires and Blackbirds have a problem with membars in the - * delay slot (SF_ERRATA_51). For safety's sake, we assume - * that the whole world needs the workaround. - */ - ENTRY(membar_enter) - membar #StoreLoad|#StoreStore - retl - nop - SET_SIZE(membar_enter) - - ENTRY(membar_exit) - membar #LoadStore|#StoreStore - retl - nop - SET_SIZE(membar_exit) - - ENTRY(membar_producer) - membar #StoreStore - retl - nop - SET_SIZE(membar_producer) - - ENTRY(membar_consumer) - membar #LoadLoad - retl - nop - SET_SIZE(membar_consumer) - -#endif /* !_KERNEL */ - -#ifdef __ELF__ -.section .note.GNU-stack,"",%progbits -#endif diff --git a/zfs/lib/libsolcompat/synonyms.h b/zfs/lib/libsolcompat/synonyms.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/tsd.h b/zfs/lib/libsolcompat/tsd.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/zfs/lib/libsolcompat/zone.c b/zfs/lib/libsolcompat/zone.c deleted file mode 100644 index f4269a76c..000000000 --- a/zfs/lib/libsolcompat/zone.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Ricardo Correia. All rights reserved. - * Use is subject to license terms. - */ - -#include -#include -#include - -zoneid_t getzoneid() -{ - return GLOBAL_ZONEID; -} - -zoneid_t getzoneidbyname(const char *name) -{ - if(name == NULL) - return GLOBAL_ZONEID; - - if(strcmp(name, GLOBAL_ZONEID_NAME) == 0) - return GLOBAL_ZONEID; - - return EINVAL; -} - -ssize_t getzonenamebyid(zoneid_t id, char *buf, size_t buflen) -{ - if(id != GLOBAL_ZONEID) - return EINVAL; - - ssize_t ret = strlen(GLOBAL_ZONEID_NAME) + 1; - - if(buf == NULL || buflen == 0) - return ret; - - strncpy(buf, GLOBAL_ZONEID_NAME, buflen); - buf[buflen - 1] = '\0'; - - return ret; -} diff --git a/zfs/lib/libzcommon/include/sys/list.h b/zfs/lib/libspl/include/sys/list.h similarity index 79% rename from zfs/lib/libzcommon/include/sys/list.h rename to zfs/lib/libspl/include/sys/list.h index c29b8959a..8339b6226 100644 --- a/zfs/lib/libzcommon/include/sys/list.h +++ b/zfs/lib/libspl/include/sys/list.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_LIST_H #define _SYS_LIST_H - +#pragma ident "%Z%%M% %I% %E% SMI" #include @@ -46,15 +45,20 @@ void list_insert_before(list_t *, void *, void *); void list_insert_head(list_t *, void *); void list_insert_tail(list_t *, void *); void list_remove(list_t *, void *); +void *list_remove_head(list_t *); +void *list_remove_tail(list_t *); void list_move_tail(list_t *, list_t *); void *list_head(list_t *); void *list_tail(list_t *); void *list_next(list_t *, void *); void *list_prev(list_t *, void *); +int list_is_empty(list_t *); + +void list_link_init(list_node_t *); +void list_link_replace(list_node_t *, list_node_t *); int list_link_active(list_node_t *); -int list_is_empty(list_t *); #ifdef __cplusplus } diff --git a/zfs/lib/libzcommon/include/sys/list_impl.h b/zfs/lib/libspl/include/sys/list_impl.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/list_impl.h rename to zfs/lib/libspl/include/sys/list_impl.h index 481aa99ca..9c42f8832 100644 --- a/zfs/lib/libzcommon/include/sys/list_impl.h +++ b/zfs/lib/libspl/include/sys/list_impl.h @@ -27,7 +27,7 @@ #ifndef _SYS_LIST_IMPL_H #define _SYS_LIST_IMPL_H - +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/lib/libumem/sys/vmem.h b/zfs/lib/libspl/include/sys/vmem.h similarity index 88% rename from zfs/lib/libumem/sys/vmem.h rename to zfs/lib/libspl/include/sys/vmem.h index fed44c3d4..abcc8b26b 100644 --- a/zfs/lib/libumem/sys/vmem.h +++ b/zfs/lib/libspl/include/sys/vmem.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_VMEM_H #define _SYS_VMEM_H -/* #pragma ident "@(#)vmem.h 1.13 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" #include @@ -73,9 +72,13 @@ extern "C" { #define VMC_IDENTIFIER 0x00040000 /* not backed by memory */ /* * internal use only; the import function uses the vmem_ximport_t interface - * and may increase the request size if it so desires + * and may increase the request size if it so desires. + * VMC_XALIGN, for use with vmem_xcreate, specifies that + * the address returned by the import function will be + * aligned according to the alignment argument. */ #define VMC_XALLOC 0x00080000 +#define VMC_XALIGN 0x00100000 #define VMC_FLAGS 0xFFFF0000 /* @@ -110,9 +113,9 @@ typedef void (vmem_free_t)(vmem_t *, void *, size_t); * Alternate import style; the requested size is passed in a pointer, * which can be increased by the import function if desired. */ -typedef void *(vmem_ximport_t)(vmem_t *, size_t *, int); +typedef void *(vmem_ximport_t)(vmem_t *, size_t *, size_t, int); -#if 0 +#ifdef _KERNEL extern vmem_t *vmem_init(const char *, void *, size_t, size_t, vmem_alloc_t *, vmem_free_t *); extern void vmem_update(void *); diff --git a/zfs/lib/libzpool/kernel.c b/zfs/lib/libspl/kernel.c similarity index 98% rename from zfs/lib/libzpool/kernel.c rename to zfs/lib/libspl/kernel.c index 71317446d..fe817cc64 100644 --- a/zfs/lib/libzpool/kernel.c +++ b/zfs/lib/libspl/kernel.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ - - #include #include #include @@ -186,9 +184,9 @@ rw_enter(krwlock_t *rwlp, krw_t rw) ASSERT(rwlp->rw_owner != curthread); if (rw == RW_READER) - (void) rw_rdlock(&rwlp->rw_lock); + VERIFY(rw_rdlock(&rwlp->rw_lock) == 0); else - (void) rw_wrlock(&rwlp->rw_lock); + VERIFY(rw_wrlock(&rwlp->rw_lock) == 0); rwlp->rw_owner = curthread; } @@ -200,7 +198,7 @@ rw_exit(krwlock_t *rwlp) ASSERT(rwlp->rw_owner != (void *)-1UL); rwlp->rw_owner = NULL; - (void) rw_unlock(&rwlp->rw_lock); + VERIFY(rw_unlock(&rwlp->rw_lock) == 0); } int @@ -428,7 +426,7 @@ vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset, len - split, offset + split); } - if (iolen < 0) + if (iolen == -1) return (errno); if (residp) *residp = len - iolen; @@ -780,12 +778,13 @@ kernel_init(int mode) dprintf("physmem = %llu pages (%.2f GB)\n", physmem, (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); - uname(&utsname); snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid()); VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1); VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1); + system_taskq_init(); + spa_init(mode); } @@ -826,14 +825,6 @@ z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen, return (ret); } -/*ARGSUSED*/ -size_t u8_textprep_str(char *i, size_t *il, char *o, size_t *ol, int nf, - size_t vers, int *err) -{ - *err = EINVAL; - return ((size_t)-1); -} - uid_t crgetuid(cred_t *cr) { diff --git a/zfs/lib/libzcommon/list.c b/zfs/lib/libspl/list.c similarity index 70% rename from zfs/lib/libzcommon/list.c rename to zfs/lib/libspl/list.c index cac8d625c..e8db13a5c 100644 --- a/zfs/lib/libzcommon/list.c +++ b/zfs/lib/libspl/list.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" /* * Generic doubly-linked list implementation @@ -41,20 +41,25 @@ #define list_insert_after_node(list, node, object) { \ list_node_t *lnew = list_d2l(list, object); \ - lnew->list_prev = node; \ - lnew->list_next = node->list_next; \ - node->list_next->list_prev = lnew; \ - node->list_next = lnew; \ + lnew->list_prev = (node); \ + lnew->list_next = (node)->list_next; \ + (node)->list_next->list_prev = lnew; \ + (node)->list_next = lnew; \ } #define list_insert_before_node(list, node, object) { \ list_node_t *lnew = list_d2l(list, object); \ - lnew->list_next = node; \ - lnew->list_prev = node->list_prev; \ - node->list_prev->list_next = lnew; \ - node->list_prev = lnew; \ + lnew->list_next = (node); \ + lnew->list_prev = (node)->list_prev; \ + (node)->list_prev->list_next = lnew; \ + (node)->list_prev = lnew; \ } +#define list_remove_node(node) \ + (node)->list_prev->list_next = (node)->list_next; \ + (node)->list_next->list_prev = (node)->list_prev; \ + (node)->list_next = (node)->list_prev = NULL + void list_create(list_t *list, size_t size, size_t offset) { @@ -83,15 +88,23 @@ list_destroy(list_t *list) void list_insert_after(list_t *list, void *object, void *nobject) { - list_node_t *lold = list_d2l(list, object); - list_insert_after_node(list, lold, nobject); + if (object == NULL) { + list_insert_head(list, nobject); + } else { + list_node_t *lold = list_d2l(list, object); + list_insert_after_node(list, lold, nobject); + } } void list_insert_before(list_t *list, void *object, void *nobject) { - list_node_t *lold = list_d2l(list, object); - list_insert_before_node(list, lold, nobject) + if (object == NULL) { + list_insert_tail(list, nobject); + } else { + list_node_t *lold = list_d2l(list, object); + list_insert_before_node(list, lold, nobject); + } } void @@ -114,9 +127,27 @@ list_remove(list_t *list, void *object) list_node_t *lold = list_d2l(list, object); ASSERT(!list_empty(list)); ASSERT(lold->list_next != NULL); - lold->list_prev->list_next = lold->list_next; - lold->list_next->list_prev = lold->list_prev; - lold->list_next = lold->list_prev = NULL; + list_remove_node(lold); +} + +void * +list_remove_head(list_t *list) +{ + list_node_t *head = list->list_head.list_next; + if (head == &list->list_head) + return (NULL); + list_remove_node(head); + return (list_object(list, head)); +} + +void * +list_remove_tail(list_t *list) +{ + list_node_t *tail = list->list_head.list_prev; + if (tail == &list->list_head) + return (NULL); + list_remove_node(tail); + return (list_object(list, tail)); } void * @@ -181,6 +212,26 @@ list_move_tail(list_t *dst, list_t *src) srcnode->list_next = srcnode->list_prev = srcnode; } +void +list_link_replace(list_node_t *lold, list_node_t *lnew) +{ + ASSERT(list_link_active(lold)); + ASSERT(!list_link_active(lnew)); + + lnew->list_next = lold->list_next; + lnew->list_prev = lold->list_prev; + lold->list_prev->list_next = lnew; + lold->list_next->list_prev = lnew; + lold->list_next = lold->list_prev = NULL; +} + +void +list_link_init(list_node_t *link) +{ + link->list_next = NULL; + link->list_prev = NULL; +} + int list_link_active(list_node_t *link) { diff --git a/zfs/lib/libsolcompat/mkdirp.c b/zfs/lib/libspl/mkdirp.c similarity index 94% rename from zfs/lib/libsolcompat/mkdirp.c rename to zfs/lib/libspl/mkdirp.c index 1c50c79ca..9c81f2a0b 100644 --- a/zfs/lib/libsolcompat/mkdirp.c +++ b/zfs/lib/libspl/mkdirp.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,17 +19,15 @@ * CDDL HEADER END */ -/* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ - /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* Copyright (c) 1988 AT&T */ +/* All Rights Reserved */ - - +#pragma ident "%Z%%M% %I% %E% SMI" /* * Creates directory and it's parents if the parents do not @@ -41,7 +38,6 @@ * Does NOT simplify pathnames with . or .. in them. */ -#include "gen_synonyms.h" #include #include #include @@ -153,7 +149,7 @@ simplify(const char *str) */ if (!str) - return (NULL); + return (NULL); /* * Get a copy of the argument. diff --git a/zfs/lib/libport/strlcat.c b/zfs/lib/libspl/strlcat.c similarity index 84% rename from zfs/lib/libport/strlcat.c rename to zfs/lib/libspl/strlcat.c index beb860ec4..07d1403dd 100644 --- a/zfs/lib/libport/strlcat.c +++ b/zfs/lib/libspl/strlcat.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +#pragma ident "%Z%%M% %I% %E% SMI" - +#include "lint.h" #include #include -#include "zfs_config.h" /* * Appends src to the dstsize buffer at dst. The append will never @@ -37,7 +37,6 @@ * the length of the pre-existing string. */ -#ifndef HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t dstsize) { @@ -58,4 +57,3 @@ strlcat(char *dst, const char *src, size_t dstsize) dst[l1+copied] = '\0'; return (l1 + l2); } -#endif diff --git a/zfs/lib/libport/strlcpy.c b/zfs/lib/libspl/strlcpy.c similarity index 81% rename from zfs/lib/libport/strlcpy.c rename to zfs/lib/libspl/strlcpy.c index 13c3e787c..7a8009b89 100644 --- a/zfs/lib/libport/strlcpy.c +++ b/zfs/lib/libspl/strlcpy.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +#pragma ident "%Z%%M% %I% %E% SMI" - +#include "lint.h" #include #include -#include "zfs_config.h" /* * Copies src to the dstsize buffer at dst. The copy will never @@ -36,7 +36,6 @@ * terminated. */ -#ifndef HAVE_STRLCPY size_t strlcpy(char *dst, const char *src, size_t len) { @@ -54,4 +53,3 @@ strlcpy(char *dst, const char *src, size_t len) dst[copied] = '\0'; return (slen); } -#endif diff --git a/zfs/lib/libport/strnlen.c b/zfs/lib/libspl/strnlen.c similarity index 92% rename from zfs/lib/libport/strnlen.c rename to zfs/lib/libspl/strnlen.c index 46d220cc0..605245b6b 100644 --- a/zfs/lib/libport/strnlen.c +++ b/zfs/lib/libspl/strnlen.c @@ -20,22 +20,20 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. + * Copyright 2008 Sun Microsystems, Inc. * All rights reserved. Use is subject to license terms. */ +#pragma ident "%Z%%M% %I% %E% SMI" - - +#include "lint.h" #include #include -#include "zfs_config.h" /* * Returns the number of non-NULL bytes in string argument, * but not more than maxlen. Does not look past str + maxlen. */ -#ifndef HAVE_STRNLEN size_t strnlen(const char *str, size_t maxlen) { @@ -47,4 +45,3 @@ strnlen(const char *str, size_t maxlen) return (ptr - str); } -#endif diff --git a/zfs/lib/libzpool/taskq.c b/zfs/lib/libspl/taskq.c similarity index 93% rename from zfs/lib/libzpool/taskq.c rename to zfs/lib/libspl/taskq.c index 6f6cfc269..93acdcf8e 100644 --- a/zfs/lib/libzpool/taskq.c +++ b/zfs/lib/libspl/taskq.c @@ -19,15 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - - #include int taskq_now; +taskq_t *system_taskq; typedef struct task { struct task *task_next; @@ -196,8 +195,8 @@ taskq_create(const char *name, int nthreads, pri_t pri, } for (t = 0; t < nthreads; t++) - VERIFY(thr_create(0, 0, taskq_thread, - tq, THR_BOUND, &tq->tq_threadlist[t]) == 0); + (void) thr_create(0, 0, taskq_thread, + tq, THR_BOUND, &tq->tq_threadlist[t]); return (tq); } @@ -227,7 +226,7 @@ taskq_destroy(taskq_t *tq) mutex_exit(&tq->tq_lock); for (t = 0; t < nthreads; t++) - VERIFY(thr_join(tq->tq_threadlist[t], NULL, NULL) == 0); + (void) thr_join(tq->tq_threadlist[t], NULL, NULL); kmem_free(tq->tq_threadlist, nthreads * sizeof (thread_t)); @@ -253,3 +252,10 @@ taskq_member(taskq_t *tq, void *t) return (0); } + +void +system_taskq_init(void) +{ + system_taskq = taskq_create("system_taskq", 64, minclsyspri, 4, 512, + TASKQ_DYNAMIC | TASKQ_PREPOPULATE); +} diff --git a/zfs/lib/libport/u8_textprep.c b/zfs/lib/libspl/u8_textprep.c similarity index 97% rename from zfs/lib/libport/u8_textprep.c rename to zfs/lib/libspl/u8_textprep.c index 95e115efc..8faf1a97e 100644 --- a/zfs/lib/libport/u8_textprep.c +++ b/zfs/lib/libspl/u8_textprep.c @@ -19,14 +19,12 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +#pragma ident "%Z%%M% %I% %E% SMI" -#include "zfs_config.h" - -#ifndef HAVE_UNICODE /* * UTF-8 text preparation functions (PSARC/2007/149, PSARC/2007/458). @@ -54,7 +52,6 @@ #include #include -#undef errno /* The maximum possible number of bytes in a UTF-8 character. */ #define U8_MB_CUR_MAX (4) @@ -337,7 +334,7 @@ const uint8_t u8_valid_max_2nd_byte[0x100] = { * specific to UTF-8 and Unicode. */ int -u8_validate(char *u8str, size_t n, char **list, int flag, int *errno) +u8_validate(char *u8str, size_t n, char **list, int flag, int *errnum) { uchar_t *ib; uchar_t *ibtail; @@ -374,13 +371,13 @@ u8_validate(char *u8str, size_t n, char **list, int flag, int *errno) */ sz = u8_number_of_bytes[*ib]; if (sz == U8_ILLEGAL_CHAR) { - *errno = EILSEQ; + *errnum = EILSEQ; return (-1); } if (sz == U8_OUT_OF_RANGE_CHAR || (validate_ucs2_range_only && sz > U8_MAX_BYTES_UCS2)) { - *errno = ERANGE; + *errnum = ERANGE; return (-1); } @@ -390,7 +387,7 @@ u8_validate(char *u8str, size_t n, char **list, int flag, int *errno) * checking higher priority then EINVAL cases. */ if ((ibtail - ib) < sz) { - *errno = EINVAL; + *errnum = EINVAL; return (-1); } @@ -410,12 +407,12 @@ u8_validate(char *u8str, size_t n, char **list, int flag, int *errno) if (second) { if (*ib < u8_valid_min_2nd_byte[f] || *ib > u8_valid_max_2nd_byte[f]) { - *errno = EILSEQ; + *errnum = EILSEQ; return (-1); } second = B_FALSE; } else if (U8_ILLEGAL_NEXT_BYTE_COMMON(*ib)) { - *errno = EILSEQ; + *errnum = EILSEQ; return (-1); } ib++; @@ -435,7 +432,7 @@ u8_validate(char *u8str, size_t n, char **list, int flag, int *errno) } if (s1 >= ib && *s2 == '\0') { - *errno = EBADF; + *errnum = EBADF; return (-1); } } @@ -569,7 +566,7 @@ do_case_conv(int uv, uchar_t *u8s, uchar_t *s, int sz, boolean_t is_it_toupper) */ static int do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, - size_t n2, boolean_t is_it_toupper, int *errno) + size_t n2, boolean_t is_it_toupper, int *errnum) { int f; int sz1; @@ -586,11 +583,11 @@ do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, * Find out what would be the byte length for this UTF-8 * character at string s1 and also find out if this is * an illegal start byte or not and if so, issue a proper - * errno and yet treat this byte as a character. + * error number and yet treat this byte as a character. */ sz1 = u8_number_of_bytes[*s1]; if (sz1 < 0) { - *errno = EILSEQ; + *errnum = EILSEQ; sz1 = 1; } @@ -615,7 +612,7 @@ do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, s1++; u8s1[1] = '\0'; } else if ((i1 + sz1) > n1) { - *errno = EINVAL; + *errnum = EINVAL; for (j = 0; (i1 + j) < n1; ) u8s1[j++] = *s1++; u8s1[j] = '\0'; @@ -627,7 +624,7 @@ do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, /* Do the same for the string s2. */ sz2 = u8_number_of_bytes[*s2]; if (sz2 < 0) { - *errno = EILSEQ; + *errnum = EILSEQ; sz2 = 1; } @@ -639,7 +636,7 @@ do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, s2++; u8s2[1] = '\0'; } else if ((i2 + sz2) > n2) { - *errno = EINVAL; + *errnum = EINVAL; for (j = 0; (i2 + j) < n2; ) u8s2[j++] = *s2++; u8s2[j] = '\0'; @@ -1386,7 +1383,7 @@ collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast, boolean_t canonical_decomposition, boolean_t compatibility_decomposition, boolean_t canonical_composition, - int *errno, u8_normalization_states_t *state) + int *errnum, u8_normalization_states_t *state) { uchar_t *s; int sz; @@ -1429,7 +1426,7 @@ collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast, sz = u8_number_of_bytes[*s]; if (sz < 0) { - *errno = EILSEQ; + *errnum = EILSEQ; u8s[0] = *s++; u8s[1] = '\0'; @@ -1449,7 +1446,7 @@ collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast, s++; u8s[1] = '\0'; } else if ((s + sz) > slast) { - *errno = EINVAL; + *errnum = EINVAL; for (i = 0; s < slast; ) u8s[i++] = *s++; @@ -1729,7 +1726,7 @@ TURN_STREAM_SAFE: */ static int do_norm_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, size_t n2, - int flag, int *errno) + int flag, int *errnum) { int result; size_t sz1; @@ -1781,7 +1778,7 @@ do_norm_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, size_t n2, is_it_toupper, is_it_tolower, canonical_decomposition, compatibility_decomposition, - canonical_composition, errno, &state); + canonical_composition, errnum, &state); } if (U8_ISASCII(*s2) && ((s2 + 1) >= s2last || @@ -1801,7 +1798,7 @@ do_norm_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, size_t n2, is_it_toupper, is_it_tolower, canonical_decomposition, compatibility_decomposition, - canonical_composition, errno, &state); + canonical_composition, errnum, &state); } /* @@ -1845,13 +1842,13 @@ do_norm_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, size_t n2, */ int u8_strcmp(const char *s1, const char *s2, size_t n, int flag, size_t uv, - int *errno) + int *errnum) { int f; size_t n1; size_t n2; - *errno = 0; + *errnum = 0; /* * Check on the requested Unicode version, case conversion, and @@ -1859,7 +1856,7 @@ u8_strcmp(const char *s1, const char *s2, size_t n, int flag, size_t uv, */ if (uv > U8_UNICODE_LATEST) { - *errno = ERANGE; + *errnum = ERANGE; uv = U8_UNICODE_LATEST; } @@ -1872,14 +1869,14 @@ u8_strcmp(const char *s1, const char *s2, size_t n, int flag, size_t uv, flag |= U8_STRCMP_CS; } else if (f != U8_STRCMP_CS && f != U8_STRCMP_CI_UPPER && f != U8_STRCMP_CI_LOWER) { - *errno = EBADF; + *errnum = EBADF; flag = U8_STRCMP_CS; } f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP); if (f && f != U8_STRCMP_NFD && f != U8_STRCMP_NFC && f != U8_STRCMP_NFKD && f != U8_STRCMP_NFKC) { - *errno = EBADF; + *errnum = EBADF; flag = U8_STRCMP_CS; } } @@ -1903,19 +1900,19 @@ u8_strcmp(const char *s1, const char *s2, size_t n, int flag, size_t uv, */ if (flag == U8_STRCMP_CI_UPPER) { return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2, - n1, n2, B_TRUE, errno)); + n1, n2, B_TRUE, errnum)); } else if (flag == U8_STRCMP_CI_LOWER) { return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2, - n1, n2, B_FALSE, errno)); + n1, n2, B_FALSE, errnum)); } return (do_norm_compare(uv, (uchar_t *)s1, (uchar_t *)s2, n1, n2, - flag, errno)); + flag, errnum)); } size_t u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, - int flag, size_t unicode_version, int *errno) + int flag, size_t unicode_version, int *errnum) { int f; int sz; @@ -1937,20 +1934,20 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, u8_normalization_states_t state; if (unicode_version > U8_UNICODE_LATEST) { - *errno = ERANGE; + *errnum = ERANGE; return ((size_t)-1); } f = flag & (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER); if (f == (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER)) { - *errno = EBADF; + *errnum = EBADF; return ((size_t)-1); } f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP); if (f && f != U8_TEXTPREP_NFD && f != U8_TEXTPREP_NFC && f != U8_TEXTPREP_NFKD && f != U8_TEXTPREP_NFKC) { - *errno = EBADF; + *errnum = EBADF; return ((size_t)-1); } @@ -1958,7 +1955,7 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, return (0); if (outarray == NULL) { - *errno = E2BIG; + *errnum = E2BIG; return ((size_t)-1); } @@ -1990,7 +1987,7 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, if (sz < 0) { if (do_not_ignore_invalid) { - *errno = EILSEQ; + *errnum = EILSEQ; ret_val = (size_t)-1; break; } @@ -2001,7 +1998,7 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, if (sz == 1) { if (ob >= obtail) { - *errno = E2BIG; + *errnum = E2BIG; ret_val = (size_t)-1; break; } @@ -2016,13 +2013,13 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, ob++; } else if ((ib + sz) > ibtail) { if (do_not_ignore_invalid) { - *errno = EINVAL; + *errnum = EINVAL; ret_val = (size_t)-1; break; } if ((obtail - ob) < (ibtail - ib)) { - *errno = E2BIG; + *errnum = E2BIG; ret_val = (size_t)-1; break; } @@ -2041,7 +2038,7 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, ib, sz, is_it_toupper); if ((obtail - ob) < i) { - *errno = E2BIG; + *errnum = E2BIG; ret_val = (size_t)-1; break; } @@ -2052,7 +2049,7 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, *ob++ = u8s[sz]; } else { if ((obtail - ob) < sz) { - *errno = E2BIG; + *errnum = E2BIG; ret_val = (size_t)-1; break; } @@ -2085,7 +2082,7 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, if (U8_ISASCII(*ib) && ((ib + 1) >= ibtail || ((ib + 1) < ibtail && U8_ISASCII(*(ib + 1))))) { if (ob >= obtail) { - *errno = E2BIG; + *errnum = E2BIG; ret_val = (size_t)-1; break; } @@ -2099,7 +2096,7 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, ib++; ob++; } else { - *errno = 0; + *errnum = 0; state = U8_STATE_START; j = collect_a_seq(unicode_version, u8s, @@ -2109,15 +2106,15 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, canonical_decomposition, compatibility_decomposition, canonical_composition, - errno, &state); + errnum, &state); - if (*errno && do_not_ignore_invalid) { + if (*errnum && do_not_ignore_invalid) { ret_val = (size_t)-1; break; } if ((obtail - ob) < j) { - *errno = E2BIG; + *errnum = E2BIG; ret_val = (size_t)-1; break; } @@ -2133,5 +2130,3 @@ u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen, return (ret_val); } - -#endif /* HAVE_UNICODE */ diff --git a/zfs/lib/libzpool/util.c b/zfs/lib/libspl/util.c similarity index 62% rename from zfs/lib/libzpool/util.c rename to zfs/lib/libspl/util.c index e7187d0d0..781edb6e8 100644 --- a/zfs/lib/libzpool/util.c +++ b/zfs/lib/libspl/util.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - - #include #include #include @@ -67,53 +65,58 @@ nicenum(uint64_t num, char *buf) } static void -show_vdev_stats(const char *desc, nvlist_t *nv, int indent) +show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent) { - nvlist_t **child; - uint_t c, children; vdev_stat_t *vs; + vdev_stat_t v0 = { 0 }; uint64_t sec; uint64_t is_log = 0; + nvlist_t **child; + uint_t c, children; char used[6], avail[6]; char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6]; char *prefix = ""; - if (indent == 0) { - (void) printf(" " + if (indent == 0 && desc != NULL) { + (void) printf(" " " capacity operations bandwidth ---- errors ----\n"); - (void) printf("description " + (void) printf("description " "used avail read write read write read write cksum\n"); } - VERIFY(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, - (uint64_t **)&vs, &c) == 0); - (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log); + if (desc != NULL) { + (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log); - if (is_log) - prefix = "log "; + if (is_log) + prefix = "log "; - sec = MAX(1, vs->vs_timestamp / NANOSEC); + if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, + (uint64_t **)&vs, &c) != 0) + vs = &v0; - nicenum(vs->vs_alloc, used); - nicenum(vs->vs_space - vs->vs_alloc, avail); - nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops); - nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops); - nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes); - nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes); - nicenum(vs->vs_read_errors, rerr); - nicenum(vs->vs_write_errors, werr); - nicenum(vs->vs_checksum_errors, cerr); + sec = MAX(1, vs->vs_timestamp / NANOSEC); - (void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n", - indent, "", - prefix, - indent + strlen(prefix) - 19 - (vs->vs_space ? 0 : 12), desc, - vs->vs_space ? 6 : 0, vs->vs_space ? used : "", - vs->vs_space ? 6 : 0, vs->vs_space ? avail : "", - rops, wops, rbytes, wbytes, rerr, werr, cerr); + nicenum(vs->vs_alloc, used); + nicenum(vs->vs_space - vs->vs_alloc, avail); + nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops); + nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops); + nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes); + nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes); + nicenum(vs->vs_read_errors, rerr); + nicenum(vs->vs_write_errors, werr); + nicenum(vs->vs_checksum_errors, cerr); - if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, - &child, &children) != 0) + (void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n", + indent, "", + prefix, + indent + strlen(prefix) - 25 - (vs->vs_space ? 0 : 12), + desc, + vs->vs_space ? 6 : 0, vs->vs_space ? used : "", + vs->vs_space ? 6 : 0, vs->vs_space ? avail : "", + rops, wops, rbytes, wbytes, rerr, werr, cerr); + } + + if (nvlist_lookup_nvlist_array(nv, ctype, &child, &children) != 0) return; for (c = 0; c < children; c++) { @@ -127,7 +130,7 @@ show_vdev_stats(const char *desc, nvlist_t *nv, int indent) (void) strcpy(tname, cname); if (nvlist_lookup_uint64(cnv, ZPOOL_CONFIG_NPARITY, &np) == 0) tname[strlen(tname)] = '0' + np; - show_vdev_stats(tname, cnv, indent + 2); + show_vdev_stats(tname, ctype, cnv, indent + 2); free(tname); } } @@ -138,14 +141,16 @@ show_pool_stats(spa_t *spa) nvlist_t *config, *nvroot; char *name; - spa_config_enter(spa, RW_READER, FTAG); - config = spa_config_generate(spa, NULL, -1ULL, B_TRUE); - spa_config_exit(spa, FTAG); + VERIFY(spa_get_stats(spa_name(spa), &config, NULL, 0) == 0); VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &name) == 0); - show_vdev_stats(name, nvroot, 0); + show_vdev_stats(name, ZPOOL_CONFIG_CHILDREN, nvroot, 0); + show_vdev_stats(NULL, ZPOOL_CONFIG_L2CACHE, nvroot, 0); + show_vdev_stats(NULL, ZPOOL_CONFIG_SPARES, nvroot, 0); + + nvlist_free(config); } diff --git a/zfs/lib/libudmu/include/udmu.h b/zfs/lib/libudmu/include/udmu.h deleted file mode 100644 index 0d5773b0b..000000000 --- a/zfs/lib/libudmu/include/udmu.h +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2006 Cluster File Systems, Inc. - * Author: Alex Tomas - * Author: Atul Vidwansa - * Author: Manoj Joseph - * - * This file is part of the Lustre file system, http://www.lustre.org - * Lustre is a trademark of Cluster File Systems, Inc. - * - * You may have signed or agreed to another license before downloading - * this software. If so, you are bound by the terms and conditions - * of that agreement, and the following does not apply to you. See the - * LICENSE file included with this distribution for more information. - * - * If you did not agree to a different license, then this copy of Lustre - * is open source software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In either case, Lustre is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * license text for more details. - */ - -#ifndef _DMU_H -#define _DMU_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define LUSTRE_ZPL_VERSION 1ULL - -#ifndef AT_TYPE -#define AT_TYPE 0x0001 -#define AT_MODE 0x0002 -#define AT_UID 0x0004 -#define AT_GID 0x0008 -#define AT_FSID 0x0010 -#define AT_NODEID 0x0020 -#define AT_NLINK 0x0040 -#define AT_SIZE 0x0080 -#define AT_ATIME 0x0100 -#define AT_MTIME 0x0200 -#define AT_CTIME 0x0400 -#define AT_RDEV 0x0800 -#define AT_BLKSIZE 0x1000 -#define AT_NBLOCKS 0x2000 -#define AT_SEQ 0x8000 -#endif - -#define ACCESSED (AT_ATIME) -#define STATE_CHANGED (AT_CTIME) -#define CONTENT_MODIFIED (AT_MTIME | AT_CTIME) - -#define LOOKUP_DIR 0x01 /* want parent dir vp */ -#define LOOKUP_XATTR 0x02 /* lookup up extended attr dir */ -#define CREATE_XATTR_DIR 0x04 /* Create extended attr dir */ - -#define S_IFDOOR 0xD000 /* door */ -#define S_IFPORT 0xE000 /* event port */ - -struct statvfs64; - -/* Data structures required for Solaris ZFS compatability */ -#if !defined(__sun__) - -#ifndef _SOL_SYS_TIME_H -typedef struct timespec timestruc_t; -#endif - -#endif - -typedef enum vtype { - VNON = 0, - VREG = 1, - VDIR = 2, - VBLK = 3, - VCHR = 4, - VLNK = 5, - VFIFO = 6, - VDOOR = 7, - VPROC = 8, - VSOCK = 9, - VPORT = 10, - VBAD = 11 -} vtype_t; - -typedef struct vnattr { - unsigned int va_mask; /* bit-mask of attributes */ - vtype_t va_type; /* vnode type (for create) */ - mode_t va_mode; /* file access mode */ - uid_t va_uid; /* owner user id */ - gid_t va_gid; /* owner group id */ - dev_t va_fsid; /* file system id (dev for now) */ - unsigned long long va_nodeid; /* node id */ - nlink_t va_nlink; /* number of references to file */ - off_t va_size; /* file size in bytes */ - timestruc_t va_atime; /* time of last access */ - timestruc_t va_mtime; /* time of last modification */ - timestruc_t va_ctime; /* time of last status change */ - dev_t va_rdev; /* device the file represents */ - unsigned int va_blksize; /* fundamental block size */ - unsigned int va_blkbits; - unsigned long long va_nblocks; /* # of blocks allocated */ - unsigned int va_seq; /* sequence number */ -} vnattr_t; - -typedef struct udmu_objset { - struct objset *os; - struct zilog *zilog; - uint64_t root; /* id of root znode */ - uint64_t unlinkedobj; -} udmu_objset_t; - - -/* definitions from dmu.h */ -#ifndef _SYS_DMU_H - -typedef struct objset objset_t; -typedef struct dmu_tx dmu_tx_t; -typedef struct dmu_buf dmu_buf_t; - -#define DMU_NEW_OBJECT (-1ULL) -#define DMU_OBJECT_END (-1ULL) - -#endif - -#ifndef _SYS_TXG_H -#define TXG_WAIT 1ULL -#define TXG_NOWAIT 2ULL -#endif - -#define ZFS_DIRENT_MAKE(type, obj) (((uint64_t)type << 60) | obj) - -#define FTAG ((char *)__func__) - -void udmu_init(); - -void udmu_fini(); - -void udmu_debug(int level); - -/* udmu object-set API */ - -int udmu_objset_open(char *osname, char *import_dir, int import, int force, udmu_objset_t *uos); - -void udmu_objset_close(udmu_objset_t *uos, int export_pool); - -int udmu_objset_statvfs(udmu_objset_t *uos, struct statvfs64 *statp); - -int udmu_objset_root(udmu_objset_t *uos, dmu_buf_t **dbp, void *tag); - -void udmu_wait_synced(udmu_objset_t *uos, dmu_tx_t *tx); - -/* udmu ZAP API */ - -int udmu_zap_lookup(udmu_objset_t *uos, dmu_buf_t *zap_db, const char *name, - void *value, int value_size, int intsize); - -void udmu_zap_create(udmu_objset_t *uos, dmu_buf_t **zap_dbp, dmu_tx_t *tx, void *tag); - -int udmu_zap_insert(udmu_objset_t *uos, dmu_buf_t *zap_db, dmu_tx_t *tx, - const char *name, void *value, int len); - -int udmu_zap_delete(udmu_objset_t *uos, dmu_buf_t *zap_db, dmu_tx_t *tx, - const char *name); - -/* udmu object API */ - -void udmu_object_create(udmu_objset_t *uos, dmu_buf_t **dbp, dmu_tx_t *tx, void *tag); - -int udmu_object_get_dmu_buf(udmu_objset_t *uos, uint64_t object, - dmu_buf_t **dbp, void *tag); - -void udmu_object_put_dmu_buf(dmu_buf_t *db, void *tag); - -uint64_t udmu_object_get_id(dmu_buf_t *db); - -int udmu_object_read(udmu_objset_t *uos, dmu_buf_t *db, uint64_t offset, - uint64_t size, void *buf); - -void udmu_object_write(udmu_objset_t *uos, dmu_buf_t *db, struct dmu_tx *tx, - uint64_t offset, uint64_t size, void *buf); - -void udmu_object_getattr(dmu_buf_t *db, vnattr_t *vap); - -void udmu_object_setattr(dmu_buf_t *db, dmu_tx_t *tx, vnattr_t *vap); - -void udmu_object_punch(udmu_objset_t *uos, dmu_buf_t *db, dmu_tx_t *tx, - uint64_t offset, uint64_t len); - -int udmu_object_delete(udmu_objset_t *uos, dmu_buf_t **db, dmu_tx_t *tx, void *tag); - -/*udmu transaction API */ - -dmu_tx_t *udmu_tx_create(udmu_objset_t *uos); - -void udmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len); - -void udmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, - uint64_t len); - -void udmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, char *name); - -void udmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object); - -void udmu_tx_abort(dmu_tx_t *tx); - -int udmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how); - -void udmu_tx_wait(dmu_tx_t *tx); - -int udmu_indblk_overhead(dmu_buf_t *db, unsigned long *used, - unsigned long *overhead); - -void udmu_tx_commit(dmu_tx_t *tx); - -void * udmu_tx_cb_create(size_t bytes); - -int udmu_tx_cb_add(dmu_tx_t *tx, void *func, void *data); - -int udmu_tx_cb_destroy(void *data); - -int udmu_object_is_zap(dmu_buf_t *); - -int udmu_indblk_overhead(dmu_buf_t *db, unsigned long *used, unsigned - long *overhead); - -int udmu_get_blocksize(dmu_buf_t *db, long *blksz); - -#ifdef __cplusplus -} -#endif - -#endif /* _DMU_H */ diff --git a/zfs/lib/libudmu/include/udmu_util.h b/zfs/lib/libudmu/include/udmu_util.h deleted file mode 100644 index 9d26da69d..000000000 --- a/zfs/lib/libudmu/include/udmu_util.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/dmu/udmu.c - * Module that interacts with the ZFS DMU and provides an abstraction - * to the rest of Lustre. - * - * Copyright (c) 2007 Cluster File Systems, Inc. - * Author: Manoj Joseph - * - * This file is part of the Lustre file system, http://www.lustre.org - * Lustre is a trademark of Cluster File Systems, Inc. - * - * You may have signed or agreed to another license before downloading - * this software. If so, you are bound by the terms and conditions - * of that agreement, and the following does not apply to you. See the - * LICENSE file included with this distribution for more information. - * - * If you did not agree to a different license, then this copy of Lustre - * is open source software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In either case, Lustre is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * license text for more details. - */ - -#ifndef _DMU_UTIL_H -#define _DMU_UTIL_H - -#ifdef DMU_OSD - -#ifdef __cplusplus -extern "C" { -#endif - -int udmu_util_lookup(udmu_objset_t *uos, dmu_buf_t *parent_db, - const char *name, dmu_buf_t **new_dbp, void *tag); - -int udmu_util_create(udmu_objset_t *uos, dmu_buf_t *parent_db, - const char *name, dmu_buf_t **new_db, void *tag); - -int udmu_util_mkdir(udmu_objset_t *uos, dmu_buf_t *parent_db, - const char *name, dmu_buf_t **new_db, void *tag); - -int udmu_util_setattr(udmu_objset_t *uos, dmu_buf_t *db, vnattr_t *va); - -int udmu_util_write(udmu_objset_t *uos, dmu_buf_t *db, - uint64_t offset, uint64_t len, void *buf); - -#ifdef __cplusplus -} -#endif - -#endif /* DMU_OSD */ - -#endif /* _DMU_UTIL_H */ diff --git a/zfs/lib/libudmu/udmu.c b/zfs/lib/libudmu/udmu.c deleted file mode 100644 index ff375967e..000000000 --- a/zfs/lib/libudmu/udmu.c +++ /dev/null @@ -1,811 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/dmu/udmu.c - * Module that interacts with the ZFS DMU and provides an abstraction - * to the rest of Lustre. - * - * Copyright (c) 2007 Cluster File Systems, Inc. - * Author: Alex Tomas - * Author: Atul Vidwansa - * Author: Manoj Joseph - * Author: Mike Pershin - * - * This file is part of the Lustre file system, http://www.lustre.org - * Lustre is a trademark of Cluster File Systems, Inc. - * - * You may have signed or agreed to another license before downloading - * this software. If so, you are bound by the terms and conditions - * of that agreement, and the following does not apply to you. See the - * LICENSE file included with this distribution for more information. - * - * If you did not agree to a different license, then this copy of Lustre - * is open source software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In either case, Lustre is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * license text for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum vtype iftovt_tab[] = { - VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, - VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VNON -}; - -ushort_t vttoif_tab[] = { - 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO, - S_IFDOOR, 0, S_IFSOCK, S_IFPORT, 0 -}; - -#define MODEMASK 07777 - -#define IFTOVT(M) (iftovt_tab[((M) & S_IFMT) >> 12]) -#define VTTOIF(T) (vttoif_tab[(int)(T)]) -#define MAKEIMODE(T, M) (VTTOIF(T) | ((M) & ~S_IFMT)) - -/* - * Debug levels. Default is LEVEL_CRITICAL. - */ -#define LEVEL_CRITICAL 1 -#define LEVEL_INFO 2 -#define LEVEL_DEBUG 3 - -static int debug_level = LEVEL_CRITICAL; - -#define CONFIG_DIR "/var/run/zfs/udmu" - -static char configdir[MAXPATHLEN]; - -static void udmu_gethrestime(struct timespec *tp) -{ - tp->tv_nsec = 0; - time(&tp->tv_sec); -} - -static void udmu_printf(int level, FILE *stream, char *message, ...) -{ - va_list args; - - if (level <= debug_level) { - va_start(args, message); - (void) vfprintf(stream, message, args); - va_end(args); - } -} - -void udmu_debug(int level) -{ - debug_level = level; -} - -void udmu_init() -{ - char cmd[MAXPATHLEN]; - struct rlimit rl = { 1024, 1024 }; - int rc; - - /* - * Set spa_config_dir to /var/run/zfs/udmu/$pid. - */ - snprintf(configdir, MAXPATHLEN, "%s/%d", CONFIG_DIR, (int)getpid()); - - snprintf(cmd, MAXPATHLEN, "mkdir -p %s", configdir); - system(cmd); - - spa_config_dir = configdir; - - (void) setvbuf(stdout, NULL, _IOLBF, 0); - (void) setrlimit(RLIMIT_NOFILE, &rl); - - /* Initialize the emulation of kernel services in userland. */ - kernel_init(FREAD | FWRITE); - - rc = dctl_server_init(configdir, 2, 2); - if (rc != 0) - fprintf(stderr, "Error calling dctl_server_init(): %i\n" - "lzpool and lzfs will not be functional!\n", rc); -} - -void udmu_fini() -{ - int rc; - - rc = dctl_server_fini(); - if (rc != 0) - fprintf(stderr, "Error calling dctl_server_fini(): %i!\n", rc); - - kernel_fini(); -} - -int udmu_objset_open(char *osname, char *import_dir, int import, int force, - udmu_objset_t *uos) -{ - int error; - char cmd[MAXPATHLEN]; - char *c; - uint64_t version = ZPL_VERSION; - int tried_import = FALSE; - - memset(uos, 0, sizeof(udmu_objset_t)); - - c = strchr(osname, '/'); - -top: - /* Let's try to open the objset */ - error = dmu_objset_open(osname, DMU_OST_ZFS, DS_MODE_STANDARD, - &uos->os); - - if (error == ENOENT && import && !tried_import) { - /* objset not found, let's try to import the pool */ - udmu_printf(LEVEL_INFO, stdout, "Importing pool %s\n", osname); - - if (c != NULL) - *c = '\0'; - - snprintf(cmd, sizeof(cmd), "lzpool import%s%s%s %s", - force ? " -F" : "", import_dir ? " -d " : "", - import_dir ? import_dir : "", osname); - - if (c != NULL) - *c = '/'; - - error = system(cmd); - - if (error) { - udmu_printf(LEVEL_CRITICAL, stderr, "\"%s\" failed:" - " %d\n", cmd, error); - return(error); - } - - tried_import = TRUE; - goto top; - } - - if (error) { - uos->os = NULL; - goto out; - } - - /* Check ZFS version */ - error = zap_lookup(uos->os, MASTER_NODE_OBJ, ZPL_VERSION_STR, 8, 1, - &version); - if (error) { - udmu_printf(LEVEL_CRITICAL, stderr, - "Error looking up ZPL VERSION"); - /* - * We can't return ENOENT because that would mean the objset - * didn't exist. - */ - error = EIO; - goto out; - } else if (version != LUSTRE_ZPL_VERSION) { - udmu_printf(LEVEL_CRITICAL, stderr, - "Mismatched versions: File system " - "is version %lld on-disk format, which is " - "incompatible with this software version %lld!", - (u_longlong_t)version, LUSTRE_ZPL_VERSION); - error = ENOTSUP; - goto out; - } - - error = zap_lookup(uos->os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, - 8, 1, &uos->root); - if (error) { - udmu_printf(LEVEL_CRITICAL, stderr, - "Error looking up ZFS root object."); - error = EIO; - goto out; - } - ASSERT(uos->root != 0); - -out: - if (error) { - if (uos->os == NULL && tried_import) { - if (c != NULL) - *c = '\0'; - spa_export(osname, NULL); - if (c != NULL) - *c = '/'; - } else if(uos->os != NULL) - udmu_objset_close(uos, tried_import); - } - - return (error); -} - -void udmu_wait_synced(udmu_objset_t *uos, dmu_tx_t *tx) -{ - /* Wait for the pool to be synced */ - txg_wait_synced(dmu_objset_pool(uos->os), - tx ? tx->tx_txg : 0ULL); -} - -void udmu_objset_close(udmu_objset_t *uos, int export_pool) -{ - spa_t *spa; - char pool_name[MAXPATHLEN]; - - ASSERT(uos->os != NULL); - spa = uos->os->os->os_spa; - - spa_config_enter(spa, RW_READER, FTAG); - strncpy(pool_name, spa_name(spa), sizeof(pool_name)); - spa_config_exit(spa, FTAG); - - udmu_wait_synced(uos, NULL); - /* close the object set */ - dmu_objset_close(uos->os); - - uos->os = NULL; - - if (export_pool) - spa_export(pool_name, NULL); -} - -int udmu_objset_statvfs(udmu_objset_t *uos, struct statvfs64 *statp) -{ - uint64_t refdbytes, availbytes, usedobjs, availobjs; - - dmu_objset_space(uos->os, &refdbytes, &availbytes, &usedobjs, - &availobjs); - - /* - * The underlying storage pool actually uses multiple block sizes. - * We report the fragsize as the smallest block size we support, - * and we report our blocksize as the filesystem's maximum blocksize. - */ - statp->f_frsize = 1ULL << SPA_MINBLOCKSHIFT; - statp->f_bsize = 1ULL << SPA_MAXBLOCKSHIFT; - - /* - * The following report "total" blocks of various kinds in the - * file system, but reported in terms of f_frsize - the - * "fragment" size. - */ - - statp->f_blocks = (refdbytes + availbytes) >> SPA_MINBLOCKSHIFT; - statp->f_bfree = availbytes >> SPA_MINBLOCKSHIFT; - statp->f_bavail = statp->f_bfree; /* no root reservation */ - - /* - * statvfs() should really be called statufs(), because it assumes - * static metadata. ZFS doesn't preallocate files, so the best - * we can do is report the max that could possibly fit in f_files, - * and that minus the number actually used in f_ffree. - * For f_ffree, report the smaller of the number of object available - * and the number of blocks (each object will take at least a block). - */ - statp->f_ffree = MIN(availobjs, statp->f_bfree); - statp->f_favail = statp->f_ffree; /* no "root reservation" */ - statp->f_files = statp->f_ffree + usedobjs; - - /* ZFSFUSE: not necessary? see 'man statfs' */ - /*(void) cmpldev(&d32, vfsp->vfs_dev); - statp->f_fsid = d32;*/ - - /* - * We're a zfs filesystem. - */ - /* ZFSFUSE: not necessary */ - /*(void) strcpy(statp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name); - - statp->f_flag = vf_to_stf(vfsp->vfs_flag);*/ - - statp->f_namemax = 256; - - return (0); -} - -static int udmu_obj2dbuf(udmu_objset_t *uos, uint64_t oid, dmu_buf_t **dbp, - void *tag) -{ - dmu_object_info_t doi; - int err; - - ASSERT(tag); - - err = dmu_bonus_hold(uos->os, oid, tag, dbp); - if (err) { - return (err); - } - - dmu_object_info_from_db(*dbp, &doi); - if (doi.doi_bonus_type != DMU_OT_ZNODE || - doi.doi_bonus_size < sizeof (znode_phys_t)) { - dmu_buf_rele(*dbp, tag); - return (EINVAL); - } - - ASSERT(*dbp); - ASSERT((*dbp)->db_object == oid); - ASSERT((*dbp)->db_offset == -1); - ASSERT((*dbp)->db_data != NULL); - - return (0); -} - -int udmu_objset_root(udmu_objset_t *uos, dmu_buf_t **dbp, void *tag) -{ - return (udmu_obj2dbuf(uos, uos->root, dbp, tag)); -} - -int udmu_zap_lookup(udmu_objset_t *uos, dmu_buf_t *zap_db, const char *name, - void *value, int value_size, int intsize) -{ - uint64_t oid; - oid = zap_db->db_object; - - /* - * value_size should be a multiple of intsize. - * intsize is 8 for micro ZAP and 1, 2, 4 or 8 for a fat ZAP. - */ - ASSERT(value_size % intsize == 0); - return (zap_lookup(uos->os, oid, name, intsize, - value_size / intsize, value)); -} - -/* - * The transaction passed to this routine must have - * udmu_tx_hold_bonus(tx, DMU_NEW_OBJECT) called and then assigned - * to a transaction group. - */ -void udmu_object_create(udmu_objset_t *uos, dmu_buf_t **dbp, dmu_tx_t *tx, - void *tag) -{ - znode_phys_t *zp; - uint64_t oid; - uint64_t gen; - timestruc_t now; - - ASSERT(tag); - - /* Assert that the transaction has been assigned to a - transaction group. */ - ASSERT(tx->tx_txg != 0); - - udmu_gethrestime(&now); - gen = dmu_tx_get_txg(tx); - - /* Create a new DMU object. */ - oid = dmu_object_alloc(uos->os, DMU_OT_PLAIN_FILE_CONTENTS, 0, - DMU_OT_ZNODE, sizeof (znode_phys_t), tx); - - dmu_object_set_blocksize(uos->os, oid, 128ULL << 10, 0, tx); - - VERIFY(0 == dmu_bonus_hold(uos->os, oid, tag, dbp)); - - dmu_buf_will_dirty(*dbp, tx); - - /* Initialize the znode physical data to zero. */ - ASSERT((*dbp)->db_size >= sizeof (znode_phys_t)); - bzero((*dbp)->db_data, (*dbp)->db_size); - zp = (*dbp)->db_data; - zp->zp_gen = gen; - zp->zp_links = 1; - ZFS_TIME_ENCODE(&now, zp->zp_crtime); - ZFS_TIME_ENCODE(&now, zp->zp_ctime); - ZFS_TIME_ENCODE(&now, zp->zp_atime); - ZFS_TIME_ENCODE(&now, zp->zp_mtime); - zp->zp_mode = MAKEIMODE(VREG, 0007); -} - - -/* - * The transaction passed to this routine must have - * udmu_tx_hold_zap(tx, DMU_NEW_OBJECT, ...) called and then assigned - * to a transaction group. - */ -void udmu_zap_create(udmu_objset_t *uos, dmu_buf_t **zap_dbp, dmu_tx_t *tx, - void *tag) -{ - znode_phys_t *zp; - uint64_t oid; - timestruc_t now; - uint64_t gen; - - ASSERT(tag); - - /* Assert that the transaction has been assigned to a - transaction group. */ - ASSERT(tx->tx_txg != 0); - - oid = 0; - udmu_gethrestime(&now); - gen = dmu_tx_get_txg(tx); - - oid = zap_create(uos->os, DMU_OT_DIRECTORY_CONTENTS, DMU_OT_ZNODE, - sizeof (znode_phys_t), tx); - - VERIFY(0 == dmu_bonus_hold(uos->os, oid, tag, zap_dbp)); - - dmu_buf_will_dirty(*zap_dbp, tx); - - bzero((*zap_dbp)->db_data, (*zap_dbp)->db_size); - zp = (*zap_dbp)->db_data; - zp->zp_size = 2; - zp->zp_links = 1; - zp->zp_gen = gen; - zp->zp_mode = MAKEIMODE(VDIR, 0007); - - ZFS_TIME_ENCODE(&now, zp->zp_crtime); - ZFS_TIME_ENCODE(&now, zp->zp_ctime); - ZFS_TIME_ENCODE(&now, zp->zp_atime); - ZFS_TIME_ENCODE(&now, zp->zp_mtime); -} - -int udmu_object_get_dmu_buf(udmu_objset_t *uos, uint64_t object, - dmu_buf_t **dbp, void *tag) -{ - return (udmu_obj2dbuf(uos, object, dbp, tag)); -} - - -/* - * The transaction passed to this routine must have - * udmu_tx_hold_bonus(tx, oid) and - * udmu_tx_hold_zap(tx, oid, ...) - * called and then assigned to a transaction group. - */ -int udmu_zap_insert(udmu_objset_t *uos, dmu_buf_t *zap_db, dmu_tx_t *tx, - const char *name, void *value, int len) -{ - uint64_t oid = zap_db->db_object; - - /* Assert that the transaction has been assigned to a - transaction group. */ - ASSERT(tx->tx_txg != 0); - - dmu_buf_will_dirty(zap_db, tx); - return (zap_add(uos->os, oid, name, 8, 1, value, tx)); -} - -/* - * The transaction passed to this routine must have - * udmu_tx_hold_zap(tx, oid, ...) called and then - * assigned to a transaction group. - */ -int udmu_zap_delete(udmu_objset_t *uos, dmu_buf_t *zap_db, dmu_tx_t *tx, - const char *name) -{ - uint64_t oid = zap_db->db_object; - - /* Assert that the transaction has been assigned to a - transaction group. */ - ASSERT(tx->tx_txg != 0); - - return (zap_remove(uos->os, oid, name, tx)); -} - -/* - * Read data from a DMU object - */ -int udmu_object_read(udmu_objset_t *uos, dmu_buf_t *db, uint64_t offset, - uint64_t size, void *buf) -{ - uint64_t oid = db->db_object; - vnattr_t va; - int rc; - - udmu_printf(LEVEL_INFO, stdout, "udmu_read(%lld, %lld, %lld)\n", - oid, offset, size); - - udmu_object_getattr(db, &va); - if (offset + size > va.va_size) { - if (va.va_size < offset) - size = 0; - else - size = va.va_size - offset; - } - - rc = dmu_read(uos->os, oid, offset, size, buf); - if (rc == 0) - return size; - else - return (-rc); -} - -/* - * Write data to a DMU object - * - * The transaction passed to this routine must have had - * udmu_tx_hold_write(tx, oid, offset, size) called and then - * assigned to a transaction group. - */ -void udmu_object_write(udmu_objset_t *uos, dmu_buf_t *db, struct dmu_tx *tx, - uint64_t offset, uint64_t size, void *buf) -{ - uint64_t oid = db->db_object; - - udmu_printf(LEVEL_INFO, stdout, "udmu_write(%lld, %lld, %lld\n", - oid, offset, size); - - dmu_write(uos->os, oid, offset, size, buf, tx); -} - -/* - * Retrieve the attributes of a DMU object - */ -void udmu_object_getattr(dmu_buf_t *db, vnattr_t *vap) -{ - dnode_t *dn = ((dmu_buf_impl_t *)db)->db_dnode; - znode_phys_t *zp = db->db_data; - - vap->va_mask = AT_ATIME | AT_MTIME | AT_CTIME | AT_MODE | AT_SIZE | - AT_UID | AT_GID | AT_TYPE | AT_NLINK | AT_RDEV; - vap->va_atime.tv_sec = zp->zp_atime[0]; - vap->va_atime.tv_nsec = 0; - vap->va_mtime.tv_sec = zp->zp_mtime[0]; - vap->va_mtime.tv_nsec = 0; - vap->va_ctime.tv_sec = zp->zp_ctime[0]; - vap->va_ctime.tv_nsec = 0; - vap->va_mode = zp->zp_mode & MODEMASK;; - vap->va_size = zp->zp_size; - vap->va_uid = zp->zp_uid; - vap->va_gid = zp->zp_gid; - vap->va_type = IFTOVT((mode_t)zp->zp_mode); - vap->va_nlink = zp->zp_links; - vap->va_rdev = zp->zp_rdev; - - vap->va_blksize = dn->dn_datablksz; - vap->va_blkbits = dn->dn_datablkshift; - /* in 512-bytes units*/ - vap->va_nblocks = DN_USED_BYTES(dn->dn_phys) >> SPA_MINBLOCKSHIFT; - vap->va_mask |= AT_NBLOCKS | AT_BLKSIZE; -} - -/* - * Set the attributes of an object - * - * The transaction passed to this routine must have - * udmu_tx_hold_bonus(tx, oid) called and then assigned - * to a transaction group. - */ -void udmu_object_setattr(dmu_buf_t *db, dmu_tx_t *tx, vnattr_t *vap) -{ - znode_phys_t *zp = db->db_data; - uint_t mask = vap->va_mask; - - /* Assert that the transaction has been assigned to a - transaction group. */ - ASSERT(tx->tx_txg != 0); - - if (mask == 0) { - return; - } - - dmu_buf_will_dirty(db, tx); - - /* - * Set each attribute requested. - * We group settings according to the locks they need to acquire. - * - * Note: you cannot set ctime directly, although it will be - * updated as a side-effect of calling this function. - */ - - if (mask & AT_MODE) - zp->zp_mode = MAKEIMODE(vap->va_type, vap->va_mode); - - if (mask & AT_UID) - zp->zp_uid = (uint64_t)vap->va_uid; - - if (mask & AT_GID) - zp->zp_gid = (uint64_t)vap->va_gid; - - if (mask & AT_SIZE) - zp->zp_size = vap->va_size; - - if (mask & AT_ATIME) - ZFS_TIME_ENCODE(&vap->va_atime, zp->zp_atime); - - if (mask & AT_MTIME) - ZFS_TIME_ENCODE(&vap->va_mtime, zp->zp_mtime); - - if (mask & AT_CTIME) - ZFS_TIME_ENCODE(&vap->va_ctime, zp->zp_ctime); - - if (mask & AT_NLINK) - zp->zp_links = vap->va_nlink; -} - -/* - * Punch/truncate an object - * - * IN: db - dmu_buf of the object to free data in. - * off - start of section to free. - * len - length of section to free (0 => to EOF). - * - * RETURN: 0 if success - * error code if failure - * - * The transaction passed to this routine must have - * udmu_tx_hold_bonus(tx, oid) and - * if off < size, udmu_tx_hold_free(tx, oid, off, len ? len : DMU_OBJECT_END) - * called and then assigned to a transaction group. - */ -void udmu_object_punch(udmu_objset_t *uos, dmu_buf_t *db, dmu_tx_t *tx, - uint64_t off, uint64_t len) -{ - znode_phys_t *zp = db->db_data; - uint64_t oid = db->db_object; - uint64_t end = off + len; - uint64_t size = zp->zp_size; - - /* Assert that the transaction has been assigned to a - transaction group. */ - ASSERT(tx->tx_txg != 0); - - /* - * Nothing to do if file already at desired length. - */ - if (len == 0 && size == off) { - return; - } - - if (end > size || len == 0) { - zp->zp_size = end; - } - - if (off < size) { - uint64_t rlen = len; - - if (len == 0) - rlen = -1; - else if (end > size) - rlen = size - off; - - VERIFY(0 == dmu_free_range(uos->os, oid, off, rlen, tx)); - } -} - -/* - * Delete a DMU object - * - * The transaction passed to this routine must have - * udmu_tx_hold_free(tx, oid, 0, DMU_OBJECT_END) called - * and then assigned to a transaction group. - * - * This will release db and set it to NULL to prevent further dbuf releases. - */ -int udmu_object_delete(udmu_objset_t *uos, dmu_buf_t **db, dmu_tx_t *tx, - void *tag) -{ - int error; - uint64_t oid = (*db)->db_object; - - /* Assert that the transaction has been assigned to a - transaction group. */ - ASSERT(tx->tx_txg != 0); - - udmu_object_put_dmu_buf(*db, tag); - *db = NULL; - - error = dmu_object_free(uos->os, oid, tx); - - return (error); -} - -/* - * Get the object id from dmu_buf_t - */ -uint64_t udmu_object_get_id(dmu_buf_t *db) -{ - ASSERT(db != NULL); - return (db->db_object); -} - -int udmu_object_is_zap(dmu_buf_t *_db) -{ - dmu_buf_impl_t *db = (dmu_buf_impl_t *) _db; - if (db->db_dnode->dn_type == DMU_OT_DIRECTORY_CONTENTS) - return 1; - return 0; -} - -/* - * Release the reference to a dmu_buf object. - */ -void udmu_object_put_dmu_buf(dmu_buf_t *db, void *tag) -{ - ASSERT(tag); - dmu_buf_rele(db, tag); -} - -dmu_tx_t *udmu_tx_create(udmu_objset_t *uos) -{ - return (dmu_tx_create(uos->os)); -} - -void udmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len) -{ - dmu_tx_hold_write(tx, object, off, len); -} - -void udmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, - uint64_t len) -{ - dmu_tx_hold_free(tx, object, off, len); -} - -void udmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, char *name) -{ - dmu_tx_hold_zap(tx, object, add, name); -} - -void udmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object) -{ - dmu_tx_hold_bonus(tx, object); -} - -void udmu_tx_abort(dmu_tx_t *tx) -{ - dmu_tx_abort(tx); -} - -int udmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how) -{ - return (dmu_tx_assign(tx, txg_how)); -} - -void udmu_tx_wait(dmu_tx_t *tx) -{ - dmu_tx_wait(tx); -} - -void udmu_tx_commit(dmu_tx_t *tx) -{ - dmu_tx_commit(tx); -} - -/* commit callback API */ -void * udmu_tx_cb_create(size_t bytes) -{ - return dmu_tx_callback_data_create(bytes); -} - -int udmu_tx_cb_add(dmu_tx_t *tx, void *func, void *data) -{ - return dmu_tx_callback_commit_add(tx, func, data); -} - -int udmu_tx_cb_destroy(void *data) -{ - return dmu_tx_callback_data_destroy(data); -} - -int udmu_indblk_overhead(dmu_buf_t *db, unsigned long *used, - unsigned long *overhead) -{ - dnode_t *dn = ((dmu_buf_impl_t *)db)->db_dnode; - - *overhead = (2 * (*used))/(1 << dn->dn_phys->dn_indblkshift); - - return 0; -} - -int udmu_get_blocksize(dmu_buf_t *db, long *blksz) -{ - dnode_t *dn = ((dmu_buf_impl_t *)db)->db_dnode; - - *blksz = (dn->dn_datablksz); - - return 0; -} diff --git a/zfs/lib/libudmu/udmu_util.c b/zfs/lib/libudmu/udmu_util.c deleted file mode 100644 index 93b7e866b..000000000 --- a/zfs/lib/libudmu/udmu_util.c +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/dmu/udmu.c - * Module that interacts with the ZFS DMU and provides an abstraction - * to the rest of Lustre. - * - * Copyright (c) 2007 Cluster File Systems, Inc. - * Author: Manoj Joseph - * - * This file is part of the Lustre file system, http://www.lustre.org - * Lustre is a trademark of Cluster File Systems, Inc. - * - * You may have signed or agreed to another license before downloading - * this software. If so, you are bound by the terms and conditions - * of that agreement, and the following does not apply to you. See the - * LICENSE file included with this distribution for more information. - * - * If you did not agree to a different license, then this copy of Lustre - * is open source software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In either case, Lustre is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * license text for more details. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static int udmu_util_object_delete(udmu_objset_t *uos, dmu_buf_t **dbp, - void *tag) -{ - dmu_tx_t *tx; - uint64_t id; - int rc; - - id = udmu_object_get_id(*dbp); - tx = udmu_tx_create(uos); - - udmu_tx_hold_free(tx, id, 0, DMU_OBJECT_END); - - rc = udmu_tx_assign(tx, TXG_WAIT); - if (rc) { - fprintf(stderr, - "udmu_util_object_delete: udmu_tx_assign failed (%d)", rc); - udmu_tx_abort(tx); - return (rc); - } - - rc = udmu_object_delete(uos, dbp, tx, tag); - if (rc) - fprintf(stderr, "udmu_object_delete() failed (%d)", rc); - - udmu_tx_commit(tx); - return rc; -} - -int udmu_util_mkdir(udmu_objset_t *uos, dmu_buf_t *parent_db, - const char *name, dmu_buf_t **new_dbp, void *tag) -{ - dmu_buf_t *db; - dmu_tx_t *tx; - uint64_t id, pid, value; - int rc; - - /* return EEXIST early to avoid object creation/deletion */ - rc = udmu_zap_lookup(uos, parent_db, name, &id, - sizeof(id), sizeof(uint64_t)); - if (rc == 0) - return EEXIST; - - pid = udmu_object_get_id(parent_db); - - tx = udmu_tx_create(uos); - udmu_tx_hold_zap(tx, DMU_NEW_OBJECT, 1, NULL); /* for zap create */ - udmu_tx_hold_bonus(tx, pid); /* for zap_add */ - udmu_tx_hold_zap(tx, pid, 1, (char *)name); /* for zap_add */ - - rc = udmu_tx_assign(tx, TXG_WAIT); - if (rc) { - fprintf(stderr, - "udmu_util_mkdir: udmu_tx_assign failed (%d)", rc); - udmu_tx_abort(tx); - return (rc); - } - - udmu_zap_create(uos, &db, tx, tag); - id = udmu_object_get_id(db); - value = ZFS_DIRENT_MAKE(0, id); - rc = udmu_zap_insert(uos, parent_db, tx, name, &value, sizeof(value)); - udmu_tx_commit(tx); - - if (rc) { - fprintf(stderr, "can't insert (%s) in zap (%d)", name, rc); - /* error handling, delete just created object */ - udmu_util_object_delete(uos, &db, tag); - } else if (new_dbp) { - *new_dbp = db; - } else { - udmu_object_put_dmu_buf(db, tag); - } - - return (rc); -} - -int udmu_util_setattr(udmu_objset_t *uos, dmu_buf_t *db, vnattr_t *va) -{ - dmu_tx_t *tx; - int rc; - - tx = udmu_tx_create(uos); - udmu_tx_hold_bonus(tx, udmu_object_get_id(db)); - - rc = udmu_tx_assign(tx, TXG_WAIT); - if (rc) { - udmu_tx_abort(tx); - } else { - udmu_object_setattr(db, tx, va); - udmu_tx_commit(tx); - } - - return (rc); -} - -int udmu_util_create(udmu_objset_t *uos, dmu_buf_t *parent_db, - const char *name, dmu_buf_t **new_dbp, void *tag) -{ - dmu_buf_t *db; - dmu_tx_t *tx; - uint64_t id, pid, value; - int rc; - - /* return EEXIST early to avoid object creation/deletion */ - rc = udmu_zap_lookup(uos, parent_db, name, &id, - sizeof(id), sizeof(uint64_t)); - if (rc == 0) - return EEXIST; - - pid = udmu_object_get_id(parent_db); - - tx = udmu_tx_create(uos); - - udmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); - udmu_tx_hold_bonus(tx, pid); - udmu_tx_hold_zap(tx, pid, 1, (char *) name); - - rc = udmu_tx_assign(tx, TXG_WAIT); - if (rc) { - fprintf(stderr, - "udmu_util_create: udmu_tx_assign failed (%d)", rc); - udmu_tx_abort(tx); - return (rc); - } - - udmu_object_create(uos, &db, tx, tag); - id = udmu_object_get_id(db); - value = ZFS_DIRENT_MAKE(0, id); - rc = udmu_zap_insert(uos, parent_db, tx, name, - &value, sizeof(value)); - udmu_tx_commit(tx); - - if (rc) { - fprintf(stderr, "can't insert new object in zap (%d)", rc); - /* error handling, delete just created object */ - udmu_util_object_delete(uos, &db, tag); - } else if (new_dbp) { - *new_dbp = db; - } else { - udmu_object_put_dmu_buf(db, tag); - } - - return (rc); -} - -int udmu_util_lookup(udmu_objset_t *uos, dmu_buf_t *parent_db, - const char *name, dmu_buf_t **new_dbp, void *tag) -{ - uint64_t id; - int rc; - - rc = udmu_zap_lookup(uos, parent_db, name, &id, - sizeof(id), sizeof(uint64_t)); - if (rc == 0) { - udmu_object_get_dmu_buf(uos, id, new_dbp, tag); - } - - return (rc); -} - -int udmu_util_write(udmu_objset_t *uos, dmu_buf_t *db, - uint64_t offset, uint64_t len, void *buf) -{ - dmu_tx_t *tx; - int set_size = 0; - uint64_t end = offset + len; - vnattr_t va; - int rc; - - udmu_object_getattr(db, &va); - - if (va.va_size < end) { - /* extending write; set file size */ - set_size = 1; - va.va_mask = AT_SIZE; - va.va_size = end; - } - - tx = udmu_tx_create(uos); - if (set_size) { - udmu_tx_hold_bonus(tx, udmu_object_get_id(db)); - } - udmu_tx_hold_write(tx, udmu_object_get_id(db), offset, len); - - rc = udmu_tx_assign(tx, TXG_WAIT); - if (rc) { - fprintf(stderr, "dmu_tx_assign() failed %d", rc); - udmu_tx_abort(tx); - return (-rc); - } - - udmu_object_write(uos, db, tx, offset, - len, buf); - if (set_size) { - udmu_object_setattr(db, tx, &va); - } - - udmu_tx_commit(tx); - - return (len); -} diff --git a/zfs/lib/libumem/config.h b/zfs/lib/libumem/config.h deleted file mode 100644 index 9994cd102..000000000 --- a/zfs/lib/libumem/config.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H - -#define UMEM_PTHREAD_MUTEX_TOO_BIG 1 - -#define HAVE_SYS_TIME_H 1 -#define HAVE_DLFCN_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_SYS_MMAN_H 1 -#define HAVE_SYS_SYSMACROS_H 1 -#define HAVE_STRINGS_H 1 - -#endif diff --git a/zfs/lib/libumem/envvar.c b/zfs/lib/libumem/envvar.c index 7452de7c5..949d33ce1 100644 --- a/zfs/lib/libumem/envvar.c +++ b/zfs/lib/libumem/envvar.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,26 +18,20 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)envvar.c 1.5 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -#include "config.h" #include #include #include #include #include -#if HAVE_DLFCN_H #include -#endif - #include "umem_base.h" #include "vmem_base.h" @@ -95,6 +88,9 @@ static arg_process_t umem_backend_process; static arg_process_t umem_log_process; +static size_t umem_size_tempval; +static arg_process_t umem_size_process; + const char *____umem_environ_msg_options = "-- UMEM_OPTIONS --"; static umem_env_item_t umem_options_items[] = { @@ -124,13 +120,31 @@ static umem_env_item_t umem_options_items[] = { NULL, 0, &umem_reap_interval }, -#ifndef _WIN32 + { "size_add", "Private", ITEM_SPECIAL, + "add a size to the cache size table", + NULL, 0, NULL, + &umem_size_tempval, &umem_size_process + }, + { "size_clear", "Private", ITEM_SPECIAL, + "clear all but the largest size from the cache size table", + NULL, 0, NULL, + &umem_size_tempval, &umem_size_process + }, + { "size_remove", "Private", ITEM_SPECIAL, + "remove a size from the cache size table", + NULL, 0, NULL, + &umem_size_tempval, &umem_size_process + }, + #ifndef UMEM_STANDALONE + { "sbrk_minalloc", "Private", ITEM_SIZE, + "The minimum allocation chunk for the sbrk(2) heap.", + NULL, 0, NULL, &vmem_sbrk_minalloc + }, { "sbrk_pagesize", "Private", ITEM_SIZE, "The preferred page size for the sbrk(2) heap.", NULL, 0, NULL, &vmem_sbrk_pagesize }, -#endif #endif { NULL, "-- end of UMEM_OPTIONS --", ITEM_INVALID } @@ -393,6 +407,49 @@ umem_log_process(const umem_env_item_t *item, const char *item_arg) return (ARG_SUCCESS); } +static int +umem_size_process(const umem_env_item_t *item, const char *item_arg) +{ + const char *name = item->item_name; + void (*action_func)(size_t); + + size_t result; + + int ret; + + if (strcmp(name, "size_clear") == 0) { + if (item_arg != NULL) { + log_message("%s: %s: does not take a value. ignored\n", + CURRENT, name); + return (ARG_BAD); + } + umem_alloc_sizes_clear(); + return (ARG_SUCCESS); + } else if (strcmp(name, "size_add") == 0) { + action_func = umem_alloc_sizes_add; + } else if (strcmp(name, "size_remove") == 0) { + action_func = umem_alloc_sizes_remove; + } else { + log_message("%s: %s: internally unrecognized\n", + CURRENT, name, name, name); + return (ARG_BAD); + } + + if (item_arg == NULL) { + log_message("%s: %s: requires a value. ignored\n", + CURRENT, name); + return (ARG_BAD); + } + + ret = item_size_process(item, item_arg); + if (ret != ARG_SUCCESS) + return (ret); + + result = *item->item_size_target; + action_func(result); + return (ARG_SUCCESS); +} + #ifndef UMEM_STANDALONE static int umem_backend_process(const umem_env_item_t *item, const char *item_arg) @@ -437,11 +494,6 @@ process_item(const umem_env_item_t *item, const char *item_arg) case ITEM_SIZE: arg_required = 1; break; - - default: - log_message("%s: %s: Invalid type. Ignored\n", - CURRENT, item->item_name); - return (1); } switch (item->item_type) { @@ -558,6 +610,7 @@ umem_setup_envvars(int invalid) static volatile enum { STATE_START, STATE_GETENV, + STATE_DLOPEN, STATE_DLSYM, STATE_FUNC, STATE_DONE @@ -582,6 +635,10 @@ umem_setup_envvars(int invalid) where = "during getenv(3C) calls -- " "getenv(3C) results ignored."; break; + case STATE_DLOPEN: + where = "during dlopen(3C) call -- " + "_umem_*() results ignored."; + break; case STATE_DLSYM: where = "during dlsym(3C) call -- " "_umem_*() results ignored."; @@ -622,12 +679,8 @@ umem_setup_envvars(int invalid) } #ifndef UMEM_STANDALONE -#ifdef _WIN32 -# define dlopen(a, b) GetModuleHandle(NULL) -# define dlsym(a, b) GetProcAddress((HANDLE)a, b) -# define dlclose(a) 0 -# define dlerror() 0 -#endif + state = STATE_DLOPEN; + /* get a handle to the "a.out" object */ if ((h = dlopen(0, RTLD_FIRST | RTLD_LAZY)) != NULL) { for (cur_env = umem_envvars; cur_env->env_name != NULL; diff --git a/zfs/lib/libumem/getpcstack.c b/zfs/lib/libumem/getpcstack.c index dffcc8591..8c3a47e19 100644 --- a/zfs/lib/libumem/getpcstack.c +++ b/zfs/lib/libumem/getpcstack.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,39 +18,21 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)getpcstack.c 1.5 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -#include "config.h" #include "misc.h" - -#if HAVE_UCONTEXT_H #include -#endif - -#if HAVE_SYS_FRAME_H #include -#endif -#if HAVE_SYS_STACK_H #include -#endif - #include -#if defined(__MACH__) -/* - * Darwin doesn't have any exposed frame info, so give it some space. - */ -#define UMEM_FRAMESIZE (2 * sizeof(long long)) - -#elif defined(__sparc) || defined(__sparcv9) +#if defined(__sparc) || defined(__sparcv9) extern void flush_windows(void); #define UMEM_FRAMESIZE MINFRAME @@ -62,7 +43,7 @@ extern void flush_windows(void); */ #define UMEM_FRAMESIZE (sizeof (struct frame)) -#elif !defined(EC_UMEM_DUMMY_PCSTACK) +#else #error needs update for new architecture #endif @@ -74,9 +55,6 @@ extern void flush_windows(void); int getpcstack(uintptr_t *pcstack, int pcstack_limit, int check_signal) { -#ifdef EC_UMEM_DUMMY_PCSTACK - return 0; -#else struct frame *fp; struct frame *nextfp, *minfp; int depth = 0; @@ -207,5 +185,4 @@ getpcstack(uintptr_t *pcstack, int pcstack_limit, int check_signal) minfp = fp; } return (depth); -#endif } diff --git a/zfs/lib/libumem/misc.h b/zfs/lib/libumem/include/misc.h similarity index 78% rename from zfs/lib/libumem/misc.h rename to zfs/lib/libumem/include/misc.h index 41e1fde3a..f1fdcc181 100644 --- a/zfs/lib/libumem/misc.h +++ b/zfs/lib/libumem/include/misc.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,29 +18,21 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ #ifndef _MISC_H #define _MISC_H -/* #pragma ident "@(#)misc.h 1.6 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -#include "config.h" #include -#ifndef _WIN32 #include -#endif -#ifdef HAVE_THREAD_H -# include -#else -# include "sol_compat.h" -#endif +#include +#include #include #ifdef __cplusplus @@ -74,9 +65,9 @@ void log_message(const char *format, ...); /* * returns the index of the (high/low) bit + 1 */ -int highbit(ulong_t) __attribute__ ((pure)); -int lowbit(ulong_t) __attribute__ ((pure)); -/* #pragma no_side_effect(highbit, lowbit) */ +int highbit(ulong_t); +int lowbit(ulong_t); +#pragma no_side_effect(highbit, lowbit) /* * Converts a hrtime_t to a timestruc_t @@ -102,9 +93,9 @@ void umem_error_enter(const char *); /* * prints error message and stack trace, then aborts. Cannot return. */ -void umem_panic(const char *format, ...) __attribute__((noreturn)); -/* #pragma does_not_return(umem_panic) */ -/* #pragma rarely_called(umem_panic) */ +void umem_panic(const char *format, ...) __NORETURN; +#pragma does_not_return(umem_panic) +#pragma rarely_called(umem_panic) /* * like umem_err, but only aborts if umem_abort > 0 @@ -121,9 +112,9 @@ void umem_err_recoverable(const char *format, ...); __umem_assert_failed(#assertion, __FILE__, __LINE__)) #endif -int __umem_assert_failed(const char *assertion, const char *file, int line) __attribute__ ((noreturn)); -/* #pragma does_not_return(__umem_assert_failed) */ -/* #pragma rarely_called(__umem_assert_failed) */ +int __umem_assert_failed(const char *assertion, const char *file, int line); +#pragma does_not_return(__umem_assert_failed) +#pragma rarely_called(__umem_assert_failed) /* * These have architecture-specific implementations. */ diff --git a/zfs/lib/libumem/include/umem.h b/zfs/lib/libumem/include/umem.h index ac6ed92ee..f8dc47529 100644 --- a/zfs/lib/libumem/include/umem.h +++ b/zfs/lib/libumem/include/umem.h @@ -27,7 +27,7 @@ #ifndef _UMEM_H #define _UMEM_H - +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libumem/umem_base.h b/zfs/lib/libumem/include/umem_base.h similarity index 89% rename from zfs/lib/libumem/umem_base.h rename to zfs/lib/libumem/include/umem_base.h index ad3cc1ef0..e78bebfb5 100644 --- a/zfs/lib/libumem/umem_base.h +++ b/zfs/lib/libumem/include/umem_base.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _UMEM_BASE_H #define _UMEM_BASE_H -/* #pragma ident "@(#)umem_base.h 1.4 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" #include @@ -50,7 +49,7 @@ extern int umem_ready; extern thread_t umem_init_thr; /* the thread doing the init */ extern int umem_init(void); /* do umem's initialization */ -/* #pragma rarely_called(umem_init) */ +#pragma rarely_called(umem_init) extern umem_log_header_t *umem_transaction_log; extern umem_log_header_t *umem_content_log; @@ -120,6 +119,10 @@ extern void umem_process_updates(void); extern void umem_cache_applyall(void (*)(umem_cache_t *)); extern void umem_cache_update(umem_cache_t *); +extern void umem_alloc_sizes_add(size_t); +extern void umem_alloc_sizes_clear(void); +extern void umem_alloc_sizes_remove(size_t); + /* * umem_fork.c: private interfaces */ diff --git a/zfs/lib/libumem/umem_impl.h b/zfs/lib/libumem/include/umem_impl.h similarity index 94% rename from zfs/lib/libumem/umem_impl.h rename to zfs/lib/libumem/include/umem_impl.h index a2e886f25..c6481d975 100644 --- a/zfs/lib/libumem/umem_impl.h +++ b/zfs/lib/libumem/include/umem_impl.h @@ -23,31 +23,18 @@ * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ #ifndef _UMEM_IMPL_H #define _UMEM_IMPL_H -/* #pragma ident "@(#)umem_impl.h 1.6 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" #include -#ifdef HAVE_SYS_SYSMACROS_H #include -#endif - -#if HAVE_SYS_TIME_H #include -#endif - #include -#ifdef HAVE_THREAD_H -# include -#else -# include "sol_compat.h" -#endif +#include #ifdef __cplusplus extern "C" { @@ -235,11 +222,7 @@ typedef struct umem_magtype { umem_cache_t *mt_cache; /* magazine cache */ } umem_magtype_t; -#if (defined(__PTHREAD_MUTEX_SIZE__) && __PTHREAD_MUTEX_SIZE__ >= 24) || defined(UMEM_PTHREAD_MUTEX_TOO_BIG) -#define UMEM_CPU_CACHE_SIZE 128 /* must be power of 2 */ -#else #define UMEM_CPU_CACHE_SIZE 64 /* must be power of 2 */ -#endif #define UMEM_CPU_PAD (UMEM_CPU_CACHE_SIZE - sizeof (mutex_t) - \ 2 * sizeof (uint_t) - 2 * sizeof (void *) - 4 * sizeof (int)) #define UMEM_CACHE_SIZE(ncpus) \ @@ -255,10 +238,7 @@ typedef struct umem_cpu_cache { int cc_prounds; /* number of objects in previous mag */ int cc_magsize; /* number of rounds in a full mag */ int cc_flags; /* CPU-local copy of cache_flags */ -#if (!defined(_LP64) || defined(UMEM_PTHREAD_MUTEX_TOO_BIG)) && !defined(_WIN32) - /* on win32, UMEM_CPU_PAD evaluates to zero, and the MS compiler - * won't allow static initialization of arrays containing structures - * that contain zero size arrays */ +#ifndef _LP64 char cc_pad[UMEM_CPU_PAD]; /* for nice alignment (32-bit) */ #endif } umem_cpu_cache_t; @@ -352,8 +332,7 @@ typedef struct umem_cpu_log_header { size_t clh_avail; int clh_chunk; int clh_hits; - char clh_pad[UMEM_CPU_CACHE_SIZE - - sizeof (mutex_t) - sizeof (char *) - + char clh_pad[64 - sizeof (mutex_t) - sizeof (char *) - sizeof (size_t) - 2 * sizeof (int)]; } umem_cpu_log_header_t; diff --git a/zfs/lib/libumem/vmem_base.h b/zfs/lib/libumem/include/vmem_base.h similarity index 88% rename from zfs/lib/libumem/vmem_base.h rename to zfs/lib/libumem/include/vmem_base.h index 06c1efc52..46ed39734 100644 --- a/zfs/lib/libumem/vmem_base.h +++ b/zfs/lib/libumem/include/vmem_base.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _VMEM_BASE_H #define _VMEM_BASE_H -/* #pragma ident "@(#)vmem_base.h 1.3 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -60,6 +59,7 @@ extern void vmem_reap(void); /* vmem_populate()-safe reap */ extern size_t pagesize; extern size_t vmem_sbrk_pagesize; +extern size_t vmem_sbrk_minalloc; extern uint_t vmem_backend; #define VMEM_BACKEND_SBRK 0x0000001 diff --git a/zfs/lib/libumem/vmem_stand.h b/zfs/lib/libumem/include/vmem_stand.h similarity index 95% rename from zfs/lib/libumem/vmem_stand.h rename to zfs/lib/libumem/include/vmem_stand.h index aeb8d11a3..fe72ed486 100644 --- a/zfs/lib/libumem/vmem_stand.h +++ b/zfs/lib/libumem/include/vmem_stand.h @@ -27,7 +27,7 @@ #ifndef _VMEM_STAND_H #define _VMEM_STAND_H -/* #pragma ident "@(#)vmem_stand.h 1.3 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" /* * additional functions defined by the standalone backend diff --git a/zfs/lib/libumem/init_lib.c b/zfs/lib/libumem/init_lib.c index bc1b3819f..dd5500a13 100644 --- a/zfs/lib/libumem/init_lib.c +++ b/zfs/lib/libumem/init_lib.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,64 +18,39 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)init_lib.c 1.2 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" /* * Initialization routines for the library version of libumem. */ -#include "config.h" #include "umem_base.h" #include "vmem_base.h" - -#if HAVE_UNISTD_H #include -#endif -#if HAVE_DLFCN_H #include -#endif - -#include -#include - -#ifdef __FreeBSD__ -#include -#endif void vmem_heap_init(void) { -#ifdef _WIN32 - vmem_backend = VMEM_BACKEND_MMAP; -#else -#if 0 void *handle = dlopen("libmapmalloc.so.1", RTLD_NOLOAD); if (handle != NULL) { -#endif log_message("sbrk backend disabled\n"); vmem_backend = VMEM_BACKEND_MMAP; -#if 0 } -#endif -#endif if ((vmem_backend & VMEM_BACKEND_MMAP) != 0) { vmem_backend = VMEM_BACKEND_MMAP; (void) vmem_mmap_arena(NULL, NULL); } else { -#ifndef _WIN32 vmem_backend = VMEM_BACKEND_SBRK; (void) vmem_sbrk_arena(NULL, NULL); -#endif } } @@ -84,66 +58,14 @@ vmem_heap_init(void) void umem_type_init(caddr_t start, size_t len, size_t pgsize) { -#ifdef _WIN32 - SYSTEM_INFO info; - GetSystemInfo(&info); - pagesize = info.dwPageSize; -#elif !defined(__FreeBSD__) pagesize = _sysconf(_SC_PAGESIZE); -#else - pagesize = PAGE_SIZE; -#endif } int umem_get_max_ncpus(void) { -#ifdef linux - /* - * HACK: sysconf() will invoke malloc() on Linux as part of reading - * in /proc/stat. To avoid recursion in the malloc replacement - * version of libumem, read /proc/stat into a static buffer. - */ - static char proc_stat[8192]; - int fd; - int ncpus = 1; - - fd = open("/proc/stat", O_RDONLY); - if (fd >= 0) { - const ssize_t n = read(fd, proc_stat, sizeof(proc_stat) - 1); - if (n >= 0) { - const char *cur; - const char *next; - - proc_stat[n] = '\0'; - cur = proc_stat; - while (*cur && (next = strstr(cur + 3, "cpu"))) { - cur = next; - } - - if (*cur) - ncpus = atoi(cur + 3) + 1; - } - - close(fd); - } - - return ncpus; - -#else /* !linux */ - -#if _SC_NPROCESSORS_ONLN - return (2 * sysconf(_SC_NPROCESSORS_ONLN)); -#elif defined(_SC_NPROCESSORS_CONF) - return (2 * sysconf(_SC_NPROCESSORS_CONF)); -#elif defined(_WIN32) - SYSTEM_INFO info; - GetSystemInfo(&info); - return info.dwNumberOfProcessors; -#else - /* XXX: determine CPU count on other platforms */ - return (1); -#endif - -#endif /* linux */ + if (thr_main() != -1) + return (2 * sysconf(_SC_NPROCESSORS_ONLN)); + else + return (1); } diff --git a/zfs/lib/libsolcompat/include/sys/mount.h b/zfs/lib/libumem/init_stand.c similarity index 59% rename from zfs/lib/libsolcompat/include/sys/mount.h rename to zfs/lib/libumem/init_stand.c index 79f63301d..a864c40f2 100644 --- a/zfs/lib/libsolcompat/include/sys/mount.h +++ b/zfs/lib/libumem/init_stand.c @@ -20,33 +20,45 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#ifndef _SOL_SYS_MOUNT_H -#define _SOL_SYS_MOUNT_H +#pragma ident "%Z%%M% %I% %E% SMI" -#include_next - -#include - -#include -#include -#include - -/* LINUX */ /* - * Some old glibc headers don't define BLKGETSIZE64 - * and we don't want to require the kernel headers + * Initialization routines for the standalone version of libumem. */ -#if !defined(BLKGETSIZE64) -#define BLKGETSIZE64 _IOR(0x12,114,size_t) -#endif -#define MS_FORCE MNT_FORCE -#define MS_OVERLAY 32768 -#define MS_NOMNTTAB 0 /* Not supported in Linux */ -#define MS_OPTIONSTR 0 /* Not necessary in Linux */ +#include "umem_base.h" +#include "vmem_base.h" -#endif +#include "vmem_stand.h" + +void +vmem_heap_init(void) +{ + vmem_backend = VMEM_BACKEND_STAND; + (void) vmem_stand_arena(NULL, NULL); +} + +void +umem_type_init(caddr_t base, size_t len, size_t pgsize) +{ + pagesize = pgsize; + + vmem_stand_init(); + (void) vmem_stand_add(base, len); +} + +int +umem_get_max_ncpus(void) +{ + return (1); +} + +int +umem_add(caddr_t base, size_t len) +{ + return (vmem_stand_add(base, len)); +} diff --git a/zfs/lib/libumem/linktest_stand.c b/zfs/lib/libumem/linktest_stand.c new file mode 100644 index 000000000..8ae9fdbec --- /dev/null +++ b/zfs/lib/libumem/linktest_stand.c @@ -0,0 +1,71 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file is used to verify that the standalone's external dependencies + * haven't changed in a way that'll break things that use it. + */ + +void __umem_assert_failed(void) {} +void atomic_add_64(void) {} +void atomic_add_32_nv(void) {} +void dladdr1(void) {} +void bcopy(void) {} +void bzero(void) {} +void exit(void) {} +void getenv(void) {} +void gethrtime(void) {} +void membar_producer(void) {} +void memcpy(void) {} +void _memcpy(void) {} +void memset(void) {} +void snprintf(void) {} +void strchr(void) {} +void strcmp(void) {} +void strlen(void) {} +void strncpy(void) {} +void strrchr(void) {} +void strtoul(void) {} +void umem_err_recoverable(void) {} +void umem_panic(void) {} +void vsnprintf(void) {} + +#ifdef __i386 +void __mul64(void) {} +void __rem64(void) {} +void __div64(void) {} + +#ifdef __GNUC__ +void __divdi3(void) {} +void __moddi3(void) {} +#endif /* __GNUC__ */ + +#endif /* __i386 */ + +int __ctype; +int errno; diff --git a/zfs/lib/libumem/malloc.c b/zfs/lib/libumem/malloc.c new file mode 100644 index 000000000..906f369d2 --- /dev/null +++ b/zfs/lib/libumem/malloc.c @@ -0,0 +1,415 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include +#include +#include +#include +#include "umem_base.h" +#include "misc.h" + +/* + * malloc_data_t is an 8-byte structure which is located "before" the pointer + * returned from {m,c,re}alloc and memalign. The first four bytes give + * information about the buffer, and the second four bytes are a status byte. + * + * See umem_impl.h for the various magic numbers used, and the size + * encode/decode macros. + * + * The 'size' of the buffer includes the tags. That is, we encode the + * argument to umem_alloc(), not the argument to malloc(). + */ + +typedef struct malloc_data { + uint32_t malloc_size; + uint32_t malloc_stat; /* = UMEM_MALLOC_ENCODE(state, malloc_size) */ +} malloc_data_t; + +void * +malloc(size_t size_arg) +{ +#ifdef _LP64 + uint32_t high_size = 0; +#endif + size_t size; + + malloc_data_t *ret; + size = size_arg + sizeof (malloc_data_t); + +#ifdef _LP64 + if (size > UMEM_SECOND_ALIGN) { + size += sizeof (malloc_data_t); + high_size = (size >> 32); + } +#endif + if (size < size_arg) { + errno = ENOMEM; /* overflow */ + return (NULL); + } + ret = (malloc_data_t *)_umem_alloc(size, UMEM_DEFAULT); + if (ret == NULL) { + if (size <= UMEM_MAXBUF) + errno = EAGAIN; + else + errno = ENOMEM; + return (NULL); +#ifdef _LP64 + } else if (high_size > 0) { + uint32_t low_size = (uint32_t)size; + + /* + * uses different magic numbers to make it harder to + * undetectably corrupt + */ + ret->malloc_size = high_size; + ret->malloc_stat = UMEM_MALLOC_ENCODE(MALLOC_MAGIC, high_size); + ret++; + + ret->malloc_size = low_size; + ret->malloc_stat = UMEM_MALLOC_ENCODE(MALLOC_OVERSIZE_MAGIC, + low_size); + ret++; + } else if (size > UMEM_SECOND_ALIGN) { + uint32_t low_size = (uint32_t)size; + + ret++; /* leave the first 8 bytes alone */ + + ret->malloc_size = low_size; + ret->malloc_stat = UMEM_MALLOC_ENCODE(MALLOC_SECOND_MAGIC, + low_size); + ret++; +#endif + } else { + ret->malloc_size = size; + ret->malloc_stat = UMEM_MALLOC_ENCODE(MALLOC_MAGIC, size); + ret++; + } + return ((void *)ret); +} + +void * +calloc(size_t nelem, size_t elsize) +{ + size_t size = nelem * elsize; + void *retval; + + if (nelem > 0 && elsize > 0 && size/nelem != elsize) { + errno = ENOMEM; /* overflow */ + return (NULL); + } + + retval = malloc(size); + if (retval == NULL) + return (NULL); + + (void) memset(retval, 0, size); + return (retval); +} + +/* + * memalign uses vmem_xalloc to do its work. + * + * in 64-bit, the memaligned buffer always has two tags. This simplifies the + * code. + */ + +void * +memalign(size_t align, size_t size_arg) +{ + size_t size; + uintptr_t phase; + + void *buf; + malloc_data_t *ret; + + size_t overhead; + + if (size_arg == 0 || align == 0 || (align & (align - 1)) != 0) { + errno = EINVAL; + return (NULL); + } + + /* + * if malloc provides the required alignment, use it. + */ + if (align <= UMEM_ALIGN || + (align <= UMEM_SECOND_ALIGN && size_arg >= UMEM_SECOND_ALIGN)) + return (malloc(size_arg)); + +#ifdef _LP64 + overhead = 2 * sizeof (malloc_data_t); +#else + overhead = sizeof (malloc_data_t); +#endif + + ASSERT(overhead <= align); + + size = size_arg + overhead; + phase = align - overhead; + + if (umem_memalign_arena == NULL && umem_init() == 0) { + errno = ENOMEM; + return (NULL); + } + + if (size < size_arg) { + errno = ENOMEM; /* overflow */ + return (NULL); + } + + buf = vmem_xalloc(umem_memalign_arena, size, align, phase, + 0, NULL, NULL, VM_NOSLEEP); + + if (buf == NULL) { + if ((size_arg + align) <= UMEM_MAXBUF) + errno = EAGAIN; + else + errno = ENOMEM; + + return (NULL); + } + + ret = (malloc_data_t *)buf; + { + uint32_t low_size = (uint32_t)size; + +#ifdef _LP64 + uint32_t high_size = (uint32_t)(size >> 32); + + ret->malloc_size = high_size; + ret->malloc_stat = UMEM_MALLOC_ENCODE(MEMALIGN_MAGIC, + high_size); + ret++; +#endif + + ret->malloc_size = low_size; + ret->malloc_stat = UMEM_MALLOC_ENCODE(MEMALIGN_MAGIC, low_size); + ret++; + } + + ASSERT(P2PHASE((uintptr_t)ret, align) == 0); + ASSERT((void *)((uintptr_t)ret - overhead) == buf); + + return ((void *)ret); +} + +void * +valloc(size_t size) +{ + return (memalign(pagesize, size)); +} + +/* + * process_free: + * + * Pulls information out of a buffer pointer, and optionally free it. + * This is used by free() and realloc() to process buffers. + * + * On failure, calls umem_err_recoverable() with an appropriate message + * On success, returns the data size through *data_size_arg, if (!is_free). + * + * Preserves errno, since free()'s semantics require it. + */ + +static int +process_free(void *buf_arg, + int do_free, /* free the buffer, or just get its size? */ + size_t *data_size_arg) /* output: bytes of data in buf_arg */ +{ + malloc_data_t *buf; + + void *base; + size_t size; + size_t data_size; + + const char *message; + int old_errno = errno; + + buf = (malloc_data_t *)buf_arg; + + buf--; + size = buf->malloc_size; + + switch (UMEM_MALLOC_DECODE(buf->malloc_stat, size)) { + + case MALLOC_MAGIC: + base = (void *)buf; + data_size = size - sizeof (malloc_data_t); + + if (do_free) + buf->malloc_stat = UMEM_FREE_PATTERN_32; + + goto process_malloc; + +#ifdef _LP64 + case MALLOC_SECOND_MAGIC: + base = (void *)(buf - 1); + data_size = size - 2 * sizeof (malloc_data_t); + + if (do_free) + buf->malloc_stat = UMEM_FREE_PATTERN_32; + + goto process_malloc; + + case MALLOC_OVERSIZE_MAGIC: { + size_t high_size; + + buf--; + high_size = buf->malloc_size; + + if (UMEM_MALLOC_DECODE(buf->malloc_stat, high_size) != + MALLOC_MAGIC) { + message = "invalid or corrupted buffer"; + break; + } + + size += high_size << 32; + + base = (void *)buf; + data_size = size - 2 * sizeof (malloc_data_t); + + if (do_free) { + buf->malloc_stat = UMEM_FREE_PATTERN_32; + (buf + 1)->malloc_stat = UMEM_FREE_PATTERN_32; + } + + goto process_malloc; + } +#endif + + case MEMALIGN_MAGIC: { + size_t overhead = sizeof (malloc_data_t); + +#ifdef _LP64 + size_t high_size; + + overhead += sizeof (malloc_data_t); + + buf--; + high_size = buf->malloc_size; + + if (UMEM_MALLOC_DECODE(buf->malloc_stat, high_size) != + MEMALIGN_MAGIC) { + message = "invalid or corrupted buffer"; + break; + } + size += high_size << 32; + + /* + * destroy the main tag's malloc_stat + */ + if (do_free) + (buf + 1)->malloc_stat = UMEM_FREE_PATTERN_32; +#endif + + base = (void *)buf; + data_size = size - overhead; + + if (do_free) + buf->malloc_stat = UMEM_FREE_PATTERN_32; + + goto process_memalign; + } + default: + if (buf->malloc_stat == UMEM_FREE_PATTERN_32) + message = "double-free or invalid buffer"; + else + message = "invalid or corrupted buffer"; + break; + } + + umem_err_recoverable("%s(%p): %s\n", + do_free? "free" : "realloc", buf_arg, message); + + errno = old_errno; + return (0); + +process_malloc: + if (do_free) + _umem_free(base, size); + else + *data_size_arg = data_size; + + errno = old_errno; + return (1); + +process_memalign: + if (do_free) + vmem_xfree(umem_memalign_arena, base, size); + else + *data_size_arg = data_size; + + errno = old_errno; + return (1); +} + +void +free(void *buf) +{ + if (buf == NULL) + return; + + /* + * Process buf, freeing it if it is not corrupt. + */ + (void) process_free(buf, 1, NULL); +} + +void * +realloc(void *buf_arg, size_t newsize) +{ + size_t oldsize; + void *buf; + + if (buf_arg == NULL) + return (malloc(newsize)); + + if (newsize == 0) { + free(buf_arg); + return (NULL); + } + + /* + * get the old data size without freeing the buffer + */ + if (process_free(buf_arg, 0, &oldsize) == 0) { + errno = EINVAL; + return (NULL); + } + + if (newsize == oldsize) /* size didn't change */ + return (buf_arg); + + buf = malloc(newsize); + if (buf == NULL) + return (NULL); + + (void) memcpy(buf, buf_arg, MIN(newsize, oldsize)); + free(buf_arg); + return (buf); +} diff --git a/zfs/lib/libumem/misc.c b/zfs/lib/libumem/misc.c index aa4d63ff0..a3da9e5b0 100644 --- a/zfs/lib/libumem/misc.c +++ b/zfs/lib/libumem/misc.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,41 +18,26 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)misc.c 1.6 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -#define _BUILDING_UMEM_MISC_C -#include "config.h" -/* #include "mtlib.h" */ -#if HAVE_UNISTD_H #include -#endif -#if HAVE_DLFCN_H #include -#endif #include #include #include #include -#if HAVE_SYS_MACHELF_H #include -#endif #include #include "misc.h" -#ifdef ECELERITY -#include "util.h" -#endif - #define UMEM_ERRFD 2 /* goes to standard error */ #define UMEM_MAX_ERROR_SIZE 4096 /* error messages are truncated to this */ @@ -77,15 +61,12 @@ static uint_t umem_error_end = 0; } static void -umem_log_enter(const char *error_str, int serious) +umem_log_enter(const char *error_str) { int looped; char c; looped = 0; -#ifdef ECELERITY - mem_printf(serious ? DCRITICAL : DINFO, "umem: %s", error_str); -#endif (void) mutex_lock(&umem_error_lock); @@ -118,7 +99,7 @@ umem_error_enter(const char *error_str) (void) write(UMEM_ERRFD, error_str, strlen(error_str)); #endif - umem_log_enter(error_str, 1); + umem_log_enter(error_str); } int @@ -204,7 +185,7 @@ log_message(const char *format, ...) (void) write(UMEM_ERRFD, buf, strlen(buf)); #endif - umem_log_enter(buf, 0); + umem_log_enter(buf); } #ifndef UMEM_STANDALONE @@ -260,7 +241,6 @@ umem_printf_warn(void *ignored, const char *format, ...) int print_sym(void *pointer) { -#if HAVE_SYS_MACHELF_H int result; Dl_info sym_info; @@ -292,7 +272,4 @@ print_sym(void *pointer) (char *)pointer - (char *)sym_info.dli_saddr); return (1); } -#else - return 0; -#endif } diff --git a/zfs/lib/libumem/sol_compat.h b/zfs/lib/libumem/sol_compat.h deleted file mode 100644 index 4b7e6cf32..000000000 --- a/zfs/lib/libumem/sol_compat.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2006 OmniTI, Inc. All rights reserved - * This header file distributed under the terms of the CDDL. - * Portions Copyright 2004 Sun Microsystems, Inc. All Rights reserved. - */ -#ifndef _EC_UMEM_SOL_COMPAT_H_ -#define _EC_UMEM_SOL_COMPAT_H_ - -#include "config.h" - -#include -#include - -#ifdef HAVE_SYS_TIME_H -#include -#endif - -#ifdef _WIN32 -# define THR_RETURN DWORD -# define THR_API WINAPI -# define INLINE __inline -#else -# define THR_RETURN void * -# define THR_API -# define INLINE inline -#endif - -#if defined(__MACH__) || defined(_WIN32) -#define NO_WEAK_SYMBOLS -#define _umem_cache_alloc(a,b) umem_cache_alloc(a,b) -#define _umem_cache_free(a,b) umem_cache_free(a,b) -#define _umem_zalloc(a,b) umem_zalloc(a,b) -#define _umem_alloc(a,b) umem_alloc(a,b) -#define _umem_alloc_align(a,b,c) umem_alloc_align(a,b,c) -#define _umem_free(a,b) umem_free(a,b) -#define _umem_free_align(a,b) umem_free_align(a,b) -#endif - -#ifdef _WIN32 -#define bcopy(s, d, n) memcpy(d, s, n) -#define bzero(m, s) memset(m, 0, s) -#endif - -typedef pthread_t thread_t; -typedef pthread_mutex_t mutex_t; -typedef pthread_cond_t cond_t; -typedef u_int64_t hrtime_t; -typedef uint32_t uint_t; -typedef unsigned long ulong_t; -typedef struct timespec timestruc_t; -typedef long long longlong_t; -typedef struct timespec timespec_t; -static INLINE hrtime_t gethrtime(void) { - struct timeval tv; - gettimeofday(&tv, NULL); - return (((u_int64_t)tv.tv_sec) << 32) | tv.tv_usec; -} -# define thr_self() pthread_self() -static INLINE thread_t _thr_self(void) { - return thr_self(); -} -#if defined(_MACH_PORT_T) -#define CPUHINT() (pthread_mach_thread_np(pthread_self())) -#endif -# define thr_sigsetmask pthread_sigmask - -#define THR_BOUND 1 -#define THR_DETACHED 2 -#define THR_DAEMON 4 - -static INLINE int thr_create(void *stack_base, - size_t stack_size, THR_RETURN (THR_API *start_func)(void*), - void *arg, long flags, thread_t *new_thread_ID) -{ - int ret; - pthread_attr_t attr; - - pthread_attr_init(&attr); - - if (flags & THR_DETACHED) { - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - } - ret = pthread_create(new_thread_ID, &attr, start_func, arg); - pthread_attr_destroy(&attr); - return ret; -} - - -# define mutex_init(mp, type, arg) pthread_mutex_init(mp, NULL) -# define mutex_lock(mp) pthread_mutex_lock(mp) -# define mutex_unlock(mp) pthread_mutex_unlock(mp) -# define mutex_destroy(mp) pthread_mutex_destroy(mp) -# define mutex_trylock(mp) pthread_mutex_trylock(mp) -# define DEFAULTMUTEX PTHREAD_MUTEX_INITIALIZER -# define DEFAULTCV PTHREAD_COND_INITIALIZER -# define MUTEX_HELD(mp) 1 /* not really, but only used in an assert */ - -# define cond_init(c, type, arg) pthread_cond_init(c, NULL) -# define cond_wait(c, m) pthread_cond_wait(c, m) -# define _cond_wait(c, m) pthread_cond_wait(c, m) -# define cond_signal(c) pthread_cond_signal(c) -# define cond_broadcast(c) pthread_cond_broadcast(c) -# define cond_destroy(c) pthread_cond_destroy(c) -# define cond_timedwait pthread_cond_timedwait -# define _cond_timedwait pthread_cond_timedwait - -#ifndef RTLD_FIRST -# define RTLD_FIRST 0 -#endif - -#ifdef ECELERITY -# include "ec_atomic.h" -#else -# ifdef _WIN32 -# define ec_atomic_inc(a) InterlockedIncrement(a) -# define ec_atomic_inc64(a) InterlockedIncrement64(a) -# elif (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__) -static INLINE uint_t ec_atomic_cas(uint_t *mem, uint_t with, uint_t cmp) -{ - uint_t prev; - __asm volatile ("lock; cmpxchgl %1, %2" - : "=a" (prev) - : "r" (with), "m" (*(mem)), "0" (cmp) - : "memory"); - return prev; -} -# elif defined(__sparc__) && defined(__GNUC__) -static INLINE uint_t ec_atomic_cas(uint_t *mem, uint_t with, uint_t cmp) -{ - __asm volatile ("cas [%3],%2,%0" - : "+r"(with), "=m"(*(mem)) - : "r"(cmp), "r"(mem), "m"(*(mem)) ); - return with; -} -# endif - -# ifndef ec_atomic_inc -static INLINE uint_t ec_atomic_inc(uint_t *mem) -{ - register uint_t last; - do { - last = *mem; - } while (ec_atomic_cas(mem, last+1, last) != last); - return ++last; -} -# endif -# ifndef ec_atomic_inc64 - /* yeah, it's not great. It's only used to bump failed allocation - * counts, so it is not critical right now. */ -# define ec_atomic_inc64(a) (*a)++ -# endif - -#endif - -#define P2PHASE(x, align) ((x) & ((align) - 1)) -#define P2ALIGN(x, align) ((x) & -(align)) -#define P2NPHASE(x, align) (-(x) & ((align) - 1)) -#define P2ROUNDUP(x, align) (-(-(x) & -(align))) -#define P2END(x, align) (-(~(x) & -(align))) -#define P2PHASEUP(x, align, phase) ((phase) - (((phase) - (x)) & -(align))) -#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1) -#define P2SAMEHIGHBIT(x, y) (((x) ^ (y)) < ((x) & (y))) -#define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0) -#define ISP2(x) (((x) & ((x) - 1)) == 0) - -/* beware! umem only uses these atomic adds for incrementing by 1 */ -#define atomic_add_64(lvalptr, delta) ec_atomic_inc64(lvalptr) -#define atomic_add_32_nv(a, b) ec_atomic_inc(a) - -#ifndef NANOSEC -#define NANOSEC 1000000000 -#endif - -#ifdef _WIN32 -#define issetugid() 0 -#elif !defined(__FreeBSD__) -#define issetugid() (geteuid() == 0) -#endif - -#define _sysconf(a) sysconf(a) -#define __NORETURN __attribute__ ((noreturn)) - -#define EC_UMEM_DUMMY_PCSTACK 1 -static INLINE int __nthreads(void) -{ - /* or more; just to force multi-threaded mode */ - return 2; -} - -#if (SIZEOF_VOID_P == 8) -# define _LP64 1 -#endif - -#ifndef MIN -# define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif -#ifndef MAX -# define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - - -#endif diff --git a/zfs/lib/libumem/stub_stand.c b/zfs/lib/libumem/stub_stand.c new file mode 100644 index 000000000..025001ff7 --- /dev/null +++ b/zfs/lib/libumem/stub_stand.c @@ -0,0 +1,129 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Stubs for the standalone to reduce the dependence on external libraries + */ + +#include +#include "misc.h" + +/*ARGSUSED*/ +int +cond_init(cond_t *cvp, int type, void *arg) +{ + return (0); +} + +/*ARGSUSED*/ +int +cond_destroy(cond_t *cvp) +{ + return (0); +} + +/*ARGSUSED*/ +int +cond_wait(cond_t *cv, mutex_t *mutex) +{ + umem_panic("attempt to wait on standumem cv %p", cv); + + /*NOTREACHED*/ + return (0); +} + +/*ARGSUSED*/ +int +cond_broadcast(cond_t *cvp) +{ + return (0); +} + +/*ARGSUSED*/ +int +pthread_setcancelstate(int state, int *oldstate) +{ + return (0); +} + +thread_t +thr_self(void) +{ + return ((thread_t)1); +} + +static mutex_t _mp = DEFAULTMUTEX; + +/*ARGSUSED*/ +int +mutex_init(mutex_t *mp, int type, void *arg) +{ + (void) memcpy(mp, &_mp, sizeof (mutex_t)); + return (0); +} + +/*ARGSUSED*/ +int +mutex_destroy(mutex_t *mp) +{ + return (0); +} + +/*ARGSUSED*/ +int +_mutex_held(mutex_t *mp) +{ + return (1); +} + +/*ARGSUSED*/ +int +mutex_lock(mutex_t *mp) +{ + return (0); +} + +/*ARGSUSED*/ +int +mutex_trylock(mutex_t *mp) +{ + return (0); +} + +/*ARGSUSED*/ +int +mutex_unlock(mutex_t *mp) +{ + return (0); +} + +int +issetugid(void) +{ + return (1); +} diff --git a/zfs/lib/libumem/sys/vmem_impl_user.h b/zfs/lib/libumem/sys/vmem_impl_user.h index c7dd5cc46..cc9da6679 100644 --- a/zfs/lib/libumem/sys/vmem_impl_user.h +++ b/zfs/lib/libumem/sys/vmem_impl_user.h @@ -23,30 +23,17 @@ * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ #ifndef _SYS_VMEM_IMPL_USER_H #define _SYS_VMEM_IMPL_USER_H -/* #pragma ident "@(#)vmem_impl_user.h 1.2 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -#if HAVE_SYS_KSTAT #include -#endif -#ifndef _WIN32 #include -#endif #include -#if HAVE_THREAD_H #include -#else -# include "sol_compat.h" -#endif -#if HAVE_SYNC_H #include -#endif #ifdef __cplusplus extern "C" { diff --git a/zfs/lib/libumem/umem.c b/zfs/lib/libumem/umem.c index 635c19e1a..a3eb0b8e6 100644 --- a/zfs/lib/libumem/umem.c +++ b/zfs/lib/libumem/umem.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,47 +18,15 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + +#pragma ident "%Z%%M% %I% %E% SMI" + /* - * Portions Copyright 2006 OmniTI, Inc. - */ - -/* #pragma ident "@(#)umem.c 1.11 05/06/08 SMI" */ - -/*! - * \mainpage Main Page - * - * \section README - * - * \include README - * - * \section Nuances - * - * There is a nuance in the behaviour of the umem port compared - * with umem on Solaris. - * - * On Linux umem will not return memory back to the OS until umem fails - * to allocate a chunk. On failure, umem_reap() will be called automatically, - * to return memory to the OS. If your code is going to be running - * for a long time on Linux and mixes calls to different memory allocators - * (e.g.: malloc()) and umem, your code will need to call - * umem_reap() periodically. - * - * This doesn't happen on Solaris, because malloc is replaced - * with umem calls, meaning that umem_reap() is called automatically. - * - * \section References - * - * http://docs.sun.com/app/docs/doc/816-5173/6mbb8advq?a=view - * - * http://access1.sun.com/techarticles/libumem.html - * - * \section Overview - * - * \code * based on usr/src/uts/common/os/kmem.c r1.64 from 2001/12/18 * * The slab allocator, as described in the following two papers: @@ -88,6 +55,7 @@ * * * KM_SLEEP v.s. UMEM_NOFAIL * + * * lock ordering * * 2. Initialization * ----------------- @@ -362,41 +330,51 @@ * If a constructor callback _does_ do a UMEM_NOFAIL allocation, and * the nofail callback does a non-local exit, we will leak the * partially-constructed buffer. - * \endcode + * + * + * 6. Lock Ordering + * ---------------- + * umem has a few more locks than kmem does, mostly in the update path. The + * overall lock ordering (earlier locks must be acquired first) is: + * + * umem_init_lock + * + * vmem_list_lock + * vmem_nosleep_lock.vmpl_mutex + * vmem_t's: + * vm_lock + * sbrk_lock + * + * umem_cache_lock + * umem_update_lock + * umem_flags_lock + * umem_cache_t's: + * cache_cpu[*].cc_lock + * cache_depot_lock + * cache_lock + * umem_log_header_t's: + * lh_cpu[*].clh_lock + * lh_lock */ -#include "config.h" -/* #include "mtlib.h" */ #include #include #include "umem_base.h" #include "vmem_base.h" -#if HAVE_SYS_PROCESSOR_H #include -#endif -#if HAVE_SYS_SYSMACROS_H #include -#endif -#if HAVE_ALLOCA_H #include -#endif #include #include #include #include #include -#if HAVE_STRINGS_H #include -#endif #include -#if HAVE_UNISTD_H #include -#endif -#if HAVE_ATOMIC_H #include -#endif #include "misc.h" @@ -413,8 +391,12 @@ size_t pagesize; * bytes, so that it will be 64-byte aligned. For all multiples of 64, * the next kmem_cache_size greater than or equal to it must be a * multiple of 64. + * + * This table must be in sorted order, from smallest to highest. The + * highest slot must be UMEM_MAXBUF, and every slot afterwards must be + * zero. */ -static const int umem_alloc_sizes[] = { +static int umem_alloc_sizes[] = { #ifdef _LP64 1 * 8, 1 * 16, @@ -433,17 +415,19 @@ static const int umem_alloc_sizes[] = { P2ALIGN(8192 / 7, 64), P2ALIGN(8192 / 6, 64), P2ALIGN(8192 / 5, 64), - P2ALIGN(8192 / 4, 64), + P2ALIGN(8192 / 4, 64), 2304, P2ALIGN(8192 / 3, 64), - P2ALIGN(8192 / 2, 64), - P2ALIGN(8192 / 1, 64), + P2ALIGN(8192 / 2, 64), 4544, + P2ALIGN(8192 / 1, 64), 9216, 4096 * 3, - 8192 * 2, + UMEM_MAXBUF, /* = 8192 * 2 */ + /* 24 slots for user expansion */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }; #define NUM_ALLOC_SIZES (sizeof (umem_alloc_sizes) / sizeof (*umem_alloc_sizes)) -#define UMEM_MAXBUF 16384 - static umem_magtype_t umem_magtype[] = { { 1, 8, 3200, 65536 }, { 3, 16, 256, 32768 }, @@ -480,21 +464,21 @@ size_t umem_minfirewall; /* hardware-enforced redzone threshold */ uint_t umem_flags = 0; -mutex_t umem_init_lock = DEFAULTMUTEX; /* locks initialization */ -cond_t umem_init_cv = DEFAULTCV; /* initialization CV */ +mutex_t umem_init_lock; /* locks initialization */ +cond_t umem_init_cv; /* initialization CV */ thread_t umem_init_thr; /* thread initializing */ int umem_init_env_ready; /* environ pre-initted */ int umem_ready = UMEM_READY_STARTUP; static umem_nofail_callback_t *nofail_callback; -static mutex_t umem_nofail_exit_lock = DEFAULTMUTEX; +static mutex_t umem_nofail_exit_lock; static thread_t umem_nofail_exit_thr; static umem_cache_t *umem_slab_cache; static umem_cache_t *umem_bufctl_cache; static umem_cache_t *umem_bufctl_audit_cache; -mutex_t umem_flags_lock = DEFAULTMUTEX; +mutex_t umem_flags_lock; static vmem_t *heap_arena; static vmem_alloc_t *heap_alloc; @@ -517,15 +501,7 @@ umem_log_header_t *umem_content_log; umem_log_header_t *umem_failure_log; umem_log_header_t *umem_slab_log; -extern thread_t _thr_self(void); -#if defined(__MACH__) || defined(__FreeBSD__) -# define CPUHINT() ((int)(_thr_self())) -#endif - -#ifndef CPUHINT -#define CPUHINT() (_thr_self()) -#endif - +#define CPUHINT() (thr_self()) #define CPUHINT_MAX() INT_MAX #define CPU(mask) (umem_cpus + (CPUHINT() & (mask))) @@ -547,12 +523,12 @@ volatile thread_t umem_st_update_thr; /* only used when single-thd */ thr_self() == umem_st_update_thr) #define IN_REAP() IN_UPDATE() -mutex_t umem_update_lock = DEFAULTMUTEX; /* cache_u{next,prev,flags} */ -cond_t umem_update_cv = DEFAULTCV; +mutex_t umem_update_lock; /* cache_u{next,prev,flags} */ +cond_t umem_update_cv; volatile hrtime_t umem_reap_next; /* min hrtime of next reap */ -mutex_t umem_cache_lock = DEFAULTMUTEX; /* inter-cache linkage only */ +mutex_t umem_cache_lock; /* inter-cache linkage only */ #ifdef UMEM_STANDALONE umem_cache_t umem_null_cache; @@ -625,12 +601,6 @@ caddr_t umem_min_stack; caddr_t umem_max_stack; -/* - * we use the _ versions, since we don't want to be cancelled. - * Actually, this is automatically taken care of by including "mtlib.h". - */ -extern int _cond_wait(cond_t *cv, mutex_t *mutex); - #define UMERR_MODIFIED 0 /* buffer modified while on freelist */ #define UMERR_REDZONE 1 /* redzone violation (write past end of buf) */ #define UMERR_DUPFREE 2 /* freed a buffer twice */ @@ -757,6 +727,8 @@ umem_remove_updates(umem_cache_t *cp) * Get it out of the active state */ while (cp->cache_uflags & UMU_ACTIVE) { + int cancel_state; + ASSERT(cp->cache_unext == NULL); cp->cache_uflags |= UMU_NOTIFY; @@ -768,7 +740,10 @@ umem_remove_updates(umem_cache_t *cp) ASSERT(umem_update_thr != thr_self() && umem_st_update_thr != thr_self()); - (void) _cond_wait(&umem_update_cv, &umem_update_lock); + (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, + &cancel_state); + (void) cond_wait(&umem_update_cv, &umem_update_lock); + (void) pthread_setcancelstate(cancel_state, NULL); } /* * Get it out of the Work Requested state @@ -1097,7 +1072,7 @@ umem_log_enter(umem_log_header_t *lhp, void *data, size_t size) { void *logspace; umem_cpu_log_header_t *clhp = - &(lhp->lh_cpu[CPU(umem_cpu_mask)->cpu_number]); + &lhp->lh_cpu[CPU(umem_cpu_mask)->cpu_number]; if (lhp == NULL || umem_logging == 0) return (NULL); @@ -1659,9 +1634,7 @@ umem_cpu_reload(umem_cpu_cache_t *ccp, umem_magazine_t *mp, int rounds) /* * Allocate a constructed object from cache cp. */ -#ifndef NO_WEAK_SYMBOLS #pragma weak umem_cache_alloc = _umem_cache_alloc -#endif void * _umem_cache_alloc(umem_cache_t *cp, int umflag) { @@ -1779,9 +1752,7 @@ retry: /* * Free a constructed object to cache cp. */ -#ifndef NO_WEAK_SYMBOLS #pragma weak umem_cache_free = _umem_cache_free -#endif void _umem_cache_free(umem_cache_t *cp, void *buf) { @@ -1886,9 +1857,7 @@ _umem_cache_free(umem_cache_t *cp, void *buf) umem_slab_free(cp, buf); } -#ifndef NO_WEAK_SYMBOLS #pragma weak umem_zalloc = _umem_zalloc -#endif void * _umem_zalloc(size_t size, int umflag) { @@ -1916,9 +1885,7 @@ retry: return (buf); } -#ifndef NO_WEAK_SYMBOLS #pragma weak umem_alloc = _umem_alloc -#endif void * _umem_alloc(size_t size, int umflag) { @@ -1954,9 +1921,7 @@ umem_alloc_retry: return (buf); } -#ifndef NO_WEAK_SYMBOLS #pragma weak umem_alloc_align = _umem_alloc_align -#endif void * _umem_alloc_align(size_t size, size_t align, int umflag) { @@ -1986,9 +1951,7 @@ umem_alloc_align_retry: return (buf); } -#ifndef NO_WEAK_SYMBOLS #pragma weak umem_free = _umem_free -#endif void _umem_free(void *buf, size_t size) { @@ -2026,9 +1989,7 @@ _umem_free(void *buf, size_t size) } } -#ifndef NO_WEAK_SYMBOLS #pragma weak umem_free_align = _umem_free_align -#endif void _umem_free_align(void *buf, size_t size) { @@ -2382,7 +2343,6 @@ umem_reap(void) (void) mutex_unlock(&umem_update_lock); return; } - umem_reaping = UMEM_REAP_ADDING; /* lock out other reaps */ (void) mutex_unlock(&umem_update_lock); @@ -2770,6 +2730,88 @@ umem_cache_destroy(umem_cache_t *cp) vmem_free(umem_cache_arena, cp, UMEM_CACHE_SIZE(umem_max_ncpus)); } +void +umem_alloc_sizes_clear(void) +{ + int i; + + umem_alloc_sizes[0] = UMEM_MAXBUF; + for (i = 1; i < NUM_ALLOC_SIZES; i++) + umem_alloc_sizes[i] = 0; +} + +void +umem_alloc_sizes_add(size_t size_arg) +{ + int i, j; + size_t size = size_arg; + + if (size == 0) { + log_message("size_add: cannot add zero-sized cache\n", + size, UMEM_MAXBUF); + return; + } + + if (size > UMEM_MAXBUF) { + log_message("size_add: %ld > %d, cannot add\n", size, + UMEM_MAXBUF); + return; + } + + if (umem_alloc_sizes[NUM_ALLOC_SIZES - 1] != 0) { + log_message("size_add: no space in alloc_table for %d\n", + size); + return; + } + + if (P2PHASE(size, UMEM_ALIGN) != 0) { + size = P2ROUNDUP(size, UMEM_ALIGN); + log_message("size_add: rounding %d up to %d\n", size_arg, + size); + } + + for (i = 0; i < NUM_ALLOC_SIZES; i++) { + int cur = umem_alloc_sizes[i]; + if (cur == size) { + log_message("size_add: %ld already in table\n", + size); + return; + } + if (cur > size) + break; + } + + for (j = NUM_ALLOC_SIZES - 1; j > i; j--) + umem_alloc_sizes[j] = umem_alloc_sizes[j-1]; + umem_alloc_sizes[i] = size; +} + +void +umem_alloc_sizes_remove(size_t size) +{ + int i; + + if (size == UMEM_MAXBUF) { + log_message("size_remove: cannot remove %ld\n", size); + return; + } + + for (i = 0; i < NUM_ALLOC_SIZES; i++) { + int cur = umem_alloc_sizes[i]; + if (cur == size) + break; + else if (cur > size || cur == 0) { + log_message("size_remove: %ld not found in table\n", + size); + return; + } + } + + for (; i + 1 < NUM_ALLOC_SIZES; i++) + umem_alloc_sizes[i] = umem_alloc_sizes[i+1]; + umem_alloc_sizes[i] = 0; +} + static int umem_cache_init(void) { @@ -2862,6 +2904,10 @@ umem_cache_init(void) for (i = 0; i < NUM_ALLOC_SIZES; i++) { size_t cache_size = umem_alloc_sizes[i]; size_t align = 0; + + if (cache_size == 0) + break; /* 0 terminates the list */ + /* * If they allocate a multiple of the coherency granularity, * they get a coherency-granularity-aligned address. @@ -2889,6 +2935,9 @@ umem_cache_init(void) for (i = 0; i < NUM_ALLOC_SIZES; i++) { size_t cache_size = umem_alloc_sizes[i]; + if (cache_size == 0) + break; /* 0 terminates the list */ + cp = umem_alloc_caches[i]; while (size <= cache_size) { @@ -2896,6 +2945,7 @@ umem_cache_init(void) size += UMEM_ALIGN; } } + ASSERT(size - UMEM_ALIGN == UMEM_MAXBUF); return (1); } @@ -2903,16 +2953,15 @@ umem_cache_init(void) * umem_startup() is called early on, and must be called explicitly if we're * the standalone version. */ -static void -umem_startup() __attribute__((constructor)); - +#ifdef UMEM_STANDALONE void -umem_startup() +#else +#pragma init(umem_startup) +static void +#endif +umem_startup(caddr_t start, size_t len, size_t pagesize, caddr_t minstack, + caddr_t maxstack) { - caddr_t start = NULL; - size_t len = 0; - size_t pagesize = 0; - #ifdef UMEM_STANDALONE int idx; /* Standalone doesn't fork */ @@ -2995,9 +3044,16 @@ umem_init(void) * someone else beat us to initializing umem. Wait * for them to complete, then return. */ - while (umem_ready == UMEM_READY_INITING) - (void) _cond_wait(&umem_init_cv, + while (umem_ready == UMEM_READY_INITING) { + int cancel_state; + + (void) pthread_setcancelstate( + PTHREAD_CANCEL_DISABLE, &cancel_state); + (void) cond_wait(&umem_init_cv, &umem_init_lock); + (void) pthread_setcancelstate( + cancel_state, NULL); + } ASSERT(umem_ready == UMEM_READY || umem_ready == UMEM_READY_INIT_FAILED); (void) mutex_unlock(&umem_init_lock); @@ -3199,10 +3255,3 @@ fail: (void) mutex_unlock(&umem_init_lock); return (0); } - -size_t -umem_cache_get_bufsize(umem_cache_t *cache) -{ - return cache->cache_bufsize; -} - diff --git a/zfs/lib/libumem/umem_agent_support.c b/zfs/lib/libumem/umem_agent_support.c index 55db5e6eb..d604b5e0c 100644 --- a/zfs/lib/libumem/umem_agent_support.c +++ b/zfs/lib/libumem/umem_agent_support.c @@ -23,18 +23,13 @@ * Copyright 2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)umem_agent_support.c 1.2 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -#include "config.h" #include "umem_base.h" #define AGENT_STACK_SIZE 4096 -#if 0 char __umem_agent_stack_beg[AGENT_STACK_SIZE]; char *__umem_agent_stack_end = __umem_agent_stack_beg + AGENT_STACK_SIZE; @@ -46,5 +41,3 @@ __umem_agent_free_bp(umem_cache_t *cp, void *buf) _umem_cache_free(cp, buf); _breakpoint(); } -#endif - diff --git a/zfs/lib/libumem/umem_fail.c b/zfs/lib/libumem/umem_fail.c index 2bafd2682..8e315b76c 100644 --- a/zfs/lib/libumem/umem_fail.c +++ b/zfs/lib/libumem/umem_fail.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,26 +18,20 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ - -/* #pragma ident "@(#)umem_fail.c 1.4 05/06/08 SMI" */ /* * Failure routines for libumem (not standalone) */ -#include "config.h" #include #include #include #include -#include #include "misc.h" @@ -74,31 +67,14 @@ firstexit(int type) static void __NORETURN umem_do_abort(void) { -#ifdef _WIN32 - abort(); -#else - if (firstexit(UMEM_EXIT_ABORT)) { + if (firstexit(UMEM_EXIT_ABORT)) (void) raise(SIGABRT); - } for (;;) { -#if defined(__FreeBSD__) - sigset_t set; - struct sigaction sa; - - sa.sa_handler = SIG_DFL; - (void) sigaction(SIGABRT, &sa, NULL); - (void) sigemptyset (&set); - (void) sigaddset (&set, SIGABRT); - (void) sigprocmask (SIG_UNBLOCK, &set, NULL); - (void) raise (SIGABRT); -#else (void) signal(SIGABRT, SIG_DFL); (void) sigrelse(SIGABRT); (void) raise(SIGABRT); -#endif } -#endif } #define SKIP_FRAMES 1 /* skip the panic frame */ @@ -137,12 +113,6 @@ umem_panic(const char *format, ...) if (format[strlen(format)-1] != '\n') umem_error_enter("\n"); -#ifdef ECELERITY - va_start(va, format); - ec_debug_vprintf(DCRITICAL, DMEM, format, va); - va_end(va); -#endif - print_stacktrace(); umem_do_abort(); @@ -171,6 +141,6 @@ __umem_assert_failed(const char *assertion, const char *file, int line) { umem_panic("Assertion failed: %s, file %s, line %d\n", assertion, file, line); - umem_do_abort(); /*NOTREACHED*/ + return (0); } diff --git a/zfs/lib/libumem/umem_fork.c b/zfs/lib/libumem/umem_fork.c index 2f701026d..4cbe81dfe 100644 --- a/zfs/lib/libumem/umem_fork.c +++ b/zfs/lib/libumem/umem_fork.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,26 +18,22 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)umem_fork.c 1.3 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -#include "config.h" -/* #include "mtlib.h" */ #include "umem_base.h" #include "vmem_base.h" -#ifndef _WIN32 #include /* - * The following functions are for pre- and post-fork1(2) handling. + * The following functions are for pre- and post-fork1(2) handling. See + * "Lock Ordering" in lib/libumem/common/umem.c for the lock ordering used. */ static void @@ -108,6 +103,10 @@ umem_lockup(void) (void) umem_init(); (void) mutex_lock(&umem_init_lock); } + + vmem_lockup(); + vmem_sbrk_lockup(); + (void) mutex_lock(&umem_cache_lock); (void) mutex_lock(&umem_update_lock); (void) mutex_lock(&umem_flags_lock); @@ -124,46 +123,30 @@ umem_lockup(void) (void) cond_broadcast(&umem_update_cv); - vmem_sbrk_lockup(); - vmem_lockup(); } static void -umem_release(void) -{ - umem_cache_t *cp; - - vmem_release(); - vmem_sbrk_release(); - - umem_release_log_header(umem_slab_log); - umem_release_log_header(umem_failure_log); - umem_release_log_header(umem_content_log); - umem_release_log_header(umem_transaction_log); - - for (cp = umem_null_cache.cache_next; cp != &umem_null_cache; - cp = cp->cache_next) - umem_release_cache(cp); - umem_release_cache(&umem_null_cache); - - (void) mutex_unlock(&umem_flags_lock); - (void) mutex_unlock(&umem_update_lock); - (void) mutex_unlock(&umem_cache_lock); - (void) mutex_unlock(&umem_init_lock); -} - -static void -umem_release_child(void) +umem_do_release(int as_child) { umem_cache_t *cp; + int cleanup_update = 0; /* - * Clean up the update state + * Clean up the update state if we are the child process and + * another thread was processing updates. */ - umem_update_thr = 0; + if (as_child) { + if (umem_update_thr != thr_self()) { + umem_update_thr = 0; + cleanup_update = 1; + } + if (umem_st_update_thr != thr_self()) { + umem_st_update_thr = 0; + cleanup_update = 1; + } + } - if (umem_st_update_thr != thr_self()) { - umem_st_update_thr = 0; + if (cleanup_update) { umem_reaping = UMEM_REAP_DONE; for (cp = umem_null_cache.cache_next; cp != &umem_null_cache; @@ -196,19 +179,45 @@ umem_release_child(void) } } - umem_release(); + umem_release_log_header(umem_slab_log); + umem_release_log_header(umem_failure_log); + umem_release_log_header(umem_content_log); + umem_release_log_header(umem_transaction_log); + + for (cp = umem_null_cache.cache_next; cp != &umem_null_cache; + cp = cp->cache_next) + umem_release_cache(cp); + umem_release_cache(&umem_null_cache); + + (void) mutex_unlock(&umem_flags_lock); + (void) mutex_unlock(&umem_update_lock); + (void) mutex_unlock(&umem_cache_lock); + + vmem_sbrk_release(); + vmem_release(); + + (void) mutex_unlock(&umem_init_lock); +} + +static void +umem_release(void) +{ + umem_do_release(0); +} + +static void +umem_release_child(void) +{ + umem_do_release(1); } -#endif void umem_forkhandler_init(void) { -#ifndef _WIN32 /* * There is no way to unregister these atfork functions, * but we don't need to. The dynamic linker and libc take * care of unregistering them if/when the library is unloaded. */ (void) pthread_atfork(umem_lockup, umem_release, umem_release_child); -#endif } diff --git a/zfs/lib/libumem/umem_update_thread.c b/zfs/lib/libumem/umem_update_thread.c index 033d606be..178c6e733 100644 --- a/zfs/lib/libumem/umem_update_thread.c +++ b/zfs/lib/libumem/umem_update_thread.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,30 +18,22 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)umem_update_thread.c 1.2 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -#include "config.h" #include "umem_base.h" #include "vmem_base.h" #include -/* - * we use the _ version, since we don't want to be cancelled. - */ -extern int _cond_timedwait(cond_t *cv, mutex_t *mutex, const timespec_t *delay); - /*ARGSUSED*/ -static THR_RETURN -THR_API umem_update_thread(void *arg) +static void * +umem_update_thread(void *arg) { struct timeval now; int in_update = 0; @@ -110,12 +101,16 @@ THR_API umem_update_thread(void *arg) * next update, or someone wakes us. */ if (umem_null_cache.cache_unext == &umem_null_cache) { + int cancel_state; timespec_t abs_time; abs_time.tv_sec = umem_update_next.tv_sec; abs_time.tv_nsec = umem_update_next.tv_usec * 1000; - (void) _cond_timedwait(&umem_update_cv, + (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, + &cancel_state); + (void) cond_timedwait(&umem_update_cv, &umem_update_lock, &abs_time); + (void) pthread_setcancelstate(cancel_state, NULL); } } /* LINTED no return statement */ @@ -124,30 +119,47 @@ THR_API umem_update_thread(void *arg) int umem_create_update_thread(void) { -#ifndef _WIN32 sigset_t sigmask, oldmask; -#endif + thread_t newthread; ASSERT(MUTEX_HELD(&umem_update_lock)); ASSERT(umem_update_thr == 0); -#ifndef _WIN32 /* * The update thread handles no signals */ (void) sigfillset(&sigmask); (void) thr_sigsetmask(SIG_BLOCK, &sigmask, &oldmask); -#endif - if (thr_create(NULL, 0, umem_update_thread, NULL, - THR_BOUND | THR_DAEMON | THR_DETACHED, &umem_update_thr) == 0) { -#ifndef _WIN32 + + /* + * drop the umem_update_lock; we cannot hold locks acquired in + * pre-fork handler while calling thr_create or thr_continue(). + */ + + (void) mutex_unlock(&umem_update_lock); + + if (thr_create(NULL, NULL, umem_update_thread, NULL, + THR_BOUND | THR_DAEMON | THR_DETACHED | THR_SUSPENDED, + &newthread) == 0) { (void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); -#endif + + (void) mutex_lock(&umem_update_lock); + /* + * due to the locking in umem_reap(), only one thread can + * ever call umem_create_update_thread() at a time. This + * must be the case for this code to work. + */ + + ASSERT(umem_update_thr == 0); + umem_update_thr = newthread; + (void) mutex_unlock(&umem_update_lock); + (void) thr_continue(newthread); + (void) mutex_lock(&umem_update_lock); + return (1); + } else { /* thr_create failed */ + (void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); + (void) mutex_lock(&umem_update_lock); } - umem_update_thr = 0; -#ifndef _WIN32 - (void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); -#endif return (0); } diff --git a/zfs/lib/libumem/vmem.c b/zfs/lib/libumem/vmem.c index 1b8981a91..040517a78 100644 --- a/zfs/lib/libumem/vmem.c +++ b/zfs/lib/libumem/vmem.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,13 +18,12 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* #pragma ident "@(#)vmem.c 1.10 05/06/08 SMI" */ - /* * For a more complete description of the main ideas, see: * @@ -37,7 +35,7 @@ * Proceedings of the 2001 Usenix Conference. * Available as /shared/sac/PSARC/2000/550/materials/vmem.pdf. * - * For the "Big Theory Statement", see usr/src/common/os/vmem.c + * For the "Big Theory Statement", see usr/src/uts/common/os/vmem.c * * 1. Overview of changes * ------------------------------ @@ -108,22 +106,12 @@ * sorted in address order. */ -#include "config.h" -/* #include "mtlib.h" */ #include -#if HAVE_ALLOCA_H #include -#endif -#ifdef HAVE_SYS_SYSMACROS_H #include -#endif #include -#if HAVE_STRINGS_H #include -#endif -#if HAVE_ATOMIC_H #include -#endif #include "vmem_base.h" #include "umem_base.h" @@ -210,12 +198,9 @@ static uint32_t vmem_id; static uint32_t vmem_populators; static vmem_seg_t vmem_seg0[VMEM_SEG_INITIAL]; static vmem_seg_t *vmem_segfree; -static mutex_t vmem_list_lock = DEFAULTMUTEX; -static mutex_t vmem_segfree_lock = DEFAULTMUTEX; -static vmem_populate_lock_t vmem_nosleep_lock = { - DEFAULTMUTEX, - 0 -}; +static mutex_t vmem_list_lock; +static mutex_t vmem_segfree_lock; +static vmem_populate_lock_t vmem_nosleep_lock; #define IN_POPULATE() (vmem_nosleep_lock.vmpl_thr == thr_self()) static vmem_t *vmem_list; static vmem_t *vmem_internal_arena; @@ -230,12 +215,6 @@ vmem_free_t *vmem_heap_free; uint32_t vmem_mtbf; /* mean time between failures [default: off] */ size_t vmem_seg_size = sizeof (vmem_seg_t); -/* - * we use the _ version, since we don't want to be cancelled. - * Actually, this is automatically taken care of by including "mtlib.h". - */ -extern int _cond_wait(cond_t *cv, mutex_t *mutex); - /* * Insert/delete from arena list (type 'a') or next-of-kin list (type 'k'). */ @@ -775,6 +754,8 @@ vmem_nextfit_alloc(vmem_t *vmp, size_t size, int vmflag) break; vsp = vsp->vs_anext; if (vsp == rotor) { + int cancel_state; + /* * We've come full circle. One possibility is that the * there's actually enough space, but the rotor itself @@ -799,7 +780,10 @@ vmem_nextfit_alloc(vmem_t *vmp, size_t size, int vmflag) 0, 0, NULL, NULL, vmflag & VM_UMFLAGS)); } vmp->vm_kstat.vk_wait++; - (void) _cond_wait(&vmp->vm_cv, &vmp->vm_lock); + (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, + &cancel_state); + (void) cond_wait(&vmp->vm_cv, &vmp->vm_lock); + (void) pthread_setcancelstate(cancel_state, NULL); vsp = rotor->vs_anext; } } @@ -867,6 +851,8 @@ vmem_xalloc(vmem_t *vmp, size_t size, size_t align, size_t phase, (void) mutex_lock(&vmp->vm_lock); for (;;) { + int cancel_state; + if (vmp->vm_nsegfree < VMEM_MINFREE && !vmem_populate(vmp, vmflag)) break; @@ -930,7 +916,7 @@ vmem_xalloc(vmem_t *vmp, size_t size, size_t align, size_t phase, start = MAX(vsp->vs_start, (uintptr_t)minaddr); end = MIN(vsp->vs_end - 1, (uintptr_t)maxaddr - 1) + 1; taddr = P2PHASEUP(start, align, phase); - if (P2CROSS(taddr, taddr + size - 1, nocross)) + if (P2BOUNDARY(taddr, size, nocross)) taddr += P2ROUNDUP(P2NPHASE(taddr, nocross), align); if ((taddr - start) + size > end - start || @@ -986,7 +972,10 @@ vmem_xalloc(vmem_t *vmp, size_t size, size_t align, size_t phase, if (vmflag & VM_NOSLEEP) break; vmp->vm_kstat.vk_wait++; - (void) _cond_wait(&vmp->vm_cv, &vmp->vm_lock); + (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, + &cancel_state); + (void) cond_wait(&vmp->vm_cv, &vmp->vm_lock); + (void) pthread_setcancelstate(cancel_state, NULL); } if (vbest != NULL) { ASSERT(vbest->vs_type == VMEM_FREE); @@ -994,7 +983,7 @@ vmem_xalloc(vmem_t *vmp, size_t size, size_t align, size_t phase, (void) vmem_seg_alloc(vmp, vbest, addr, size); (void) mutex_unlock(&vmp->vm_lock); ASSERT(P2PHASE(addr, align) == phase); - ASSERT(!P2CROSS(addr, addr + size - 1, nocross)); + ASSERT(!P2BOUNDARY(addr, size, nocross)); ASSERT(addr >= (uintptr_t)minaddr); ASSERT(addr + size - 1 <= (uintptr_t)maxaddr - 1); return ((void *)addr); diff --git a/zfs/lib/libumem/vmem_base.c b/zfs/lib/libumem/vmem_base.c index d43ecded4..6b1c07e1b 100644 --- a/zfs/lib/libumem/vmem_base.c +++ b/zfs/lib/libumem/vmem_base.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,15 +18,14 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* #pragma ident "@(#)vmem_base.c 1.6 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" -/* #include "mtlib.h" */ -#include "config.h" #include "vmem_base.h" #include "umem_base.h" diff --git a/zfs/lib/libumem/vmem_mmap.c b/zfs/lib/libumem/vmem_mmap.c index f59e48dc1..41c1ee5e7 100644 --- a/zfs/lib/libumem/vmem_mmap.c +++ b/zfs/lib/libumem/vmem_mmap.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,29 +18,18 @@ * * CDDL HEADER END */ + /* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)vmem_mmap.c 1.2 05/06/08 SMI" */ - -#include "config.h" -#include - -#if HAVE_SYS_MMAN_H -#include -#endif - -#ifdef HAVE_SYS_SYSMACROS_H -#include -#endif +#pragma ident "%Z%%M% %I% %E% SMI" #include - +#include +#include +#include #include "vmem_base.h" #define ALLOC_PROT PROT_READ | PROT_WRITE | PROT_EXEC @@ -50,11 +38,7 @@ #define ALLOC_FLAGS MAP_PRIVATE | MAP_ANON #define FREE_FLAGS MAP_PRIVATE | MAP_ANON | MAP_NORESERVE -#ifdef MAP_ALIGN #define CHUNKSIZE (64*1024) /* 64 kilobytes */ -#else -static size_t CHUNKSIZE; -#endif static vmem_t *mmap_heap; @@ -65,12 +49,9 @@ vmem_mmap_alloc(vmem_t *src, size_t size, int vmflags) int old_errno = errno; ret = vmem_alloc(src, size, vmflags); -#ifndef _WIN32 - if (ret != NULL - && + if (ret != NULL && mmap(ret, size, ALLOC_PROT, ALLOC_FLAGS | MAP_FIXED, -1, 0) == - MAP_FAILED - ) { + MAP_FAILED) { vmem_free(src, ret, size); vmem_reap(); @@ -78,7 +59,6 @@ vmem_mmap_alloc(vmem_t *src, size_t size, int vmflags) errno = old_errno; return (NULL); } -#endif errno = old_errno; return (ret); @@ -88,11 +68,7 @@ static void vmem_mmap_free(vmem_t *src, void *addr, size_t size) { int old_errno = errno; -#ifdef _WIN32 - VirtualFree(addr, size, MEM_RELEASE); -#else (void) mmap(addr, size, FREE_PROT, FREE_FLAGS | MAP_FIXED, -1, 0); -#endif vmem_free(src, addr, size); errno = old_errno; } @@ -113,22 +89,8 @@ vmem_mmap_top_alloc(vmem_t *src, size_t size, int vmflags) /* * Need to grow the heap */ -#ifdef _WIN32 - buf = VirtualAlloc(NULL, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - if (buf == NULL) buf = MAP_FAILED; -#else - buf = mmap( -#ifdef MAP_ALIGN - (void *)CHUNKSIZE, -#else - 0, -#endif - size, FREE_PROT, FREE_FLAGS -#ifdef MAP_ALIGN - | MAP_ALIGN -#endif - , -1, 0); -#endif + buf = mmap((void *)CHUNKSIZE, size, FREE_PROT, FREE_FLAGS | MAP_ALIGN, + -1, 0); if (buf != MAP_FAILED) { ret = _vmem_extend_alloc(src, buf, size, size, vmflags); @@ -154,24 +116,10 @@ vmem_mmap_top_alloc(vmem_t *src, size_t size, int vmflags) vmem_t * vmem_mmap_arena(vmem_alloc_t **a_out, vmem_free_t **f_out) { -#ifdef _WIN32 - SYSTEM_INFO info; - size_t pagesize; -#else - size_t pagesize = _sysconf(_SC_PAGESIZE); -#endif - -#ifdef _WIN32 - GetSystemInfo(&info); - pagesize = info.dwPageSize; - CHUNKSIZE = info.dwAllocationGranularity; -#elif !defined(MAP_ALIGN) - CHUNKSIZE = pagesize; -#endif - + size_t pagesize = sysconf(_SC_PAGESIZE); + if (mmap_heap == NULL) { - mmap_heap = vmem_init("mmap_top", - CHUNKSIZE, + mmap_heap = vmem_init("mmap_top", CHUNKSIZE, vmem_mmap_top_alloc, vmem_free, "mmap_heap", NULL, 0, pagesize, vmem_mmap_alloc, vmem_mmap_free); diff --git a/zfs/lib/libumem/vmem_sbrk.c b/zfs/lib/libumem/vmem_sbrk.c index a7c91bbbd..20bfb7345 100644 --- a/zfs/lib/libumem/vmem_sbrk.c +++ b/zfs/lib/libumem/vmem_sbrk.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,15 +18,13 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* - * Portions Copyright 2006 OmniTI, Inc. - */ -/* #pragma ident "@(#)vmem_sbrk.c 1.4 05/06/08 SMI" */ +#pragma ident "%Z%%M% %I% %E% SMI" /* * The structure of the sbrk backend: @@ -54,13 +51,9 @@ * before calling sbrk(). */ -#include "config.h" -/* #include "mtlib.h" */ #include #include -#ifdef HAVE_SYS_SYSMACROS_H #include -#endif #include #include @@ -70,7 +63,8 @@ size_t vmem_sbrk_pagesize = 0; /* the preferred page size of the heap */ -#define MIN_ALLOC (64*1024) +#define VMEM_SBRK_MINALLOC (64 * 1024) +size_t vmem_sbrk_minalloc = VMEM_SBRK_MINALLOC; /* minimum allocation */ static size_t real_pagesize; static vmem_t *sbrk_heap; @@ -91,59 +85,6 @@ static sbrk_fail_t sbrk_fails = { static mutex_t sbrk_faillock = DEFAULTMUTEX; -/* - * _sbrk_grow_aligned() aligns the old break to a low_align boundry, - * adds min_size, aligns to a high_align boundry, and calls _brk_unlocked() - * to set the new break. The low_aligned-aligned value is returned, and - * the actual space allocated is returned through actual_size. - * - * Unlike sbrk(2), _sbrk_grow_aligned takes an unsigned size, and does - * not allow shrinking the heap. - */ -void * -_sbrk_grow_aligned(size_t min_size, size_t low_align, size_t high_align, - size_t *actual_size) -{ - uintptr_t old_brk; - uintptr_t ret_brk; - uintptr_t high_brk; - uintptr_t new_brk; - int brk_result; - -#define ALIGNSZ 16 -#define BRKALIGN(x) (caddr_t)P2ROUNDUP((uintptr_t)(x), ALIGNSZ) - - if ((low_align & (low_align - 1)) != 0 || - (high_align & (high_align - 1)) != 0) { - errno = EINVAL; - return ((void *)-1); - } - low_align = MAX(low_align, ALIGNSZ); - high_align = MAX(high_align, ALIGNSZ); - - old_brk = (uintptr_t)BRKALIGN(sbrk(0)); - ret_brk = P2ROUNDUP(old_brk, low_align); - high_brk = ret_brk + min_size; - new_brk = P2ROUNDUP(high_brk, high_align); - - /* - * Check for overflow - */ - if (ret_brk < old_brk || high_brk < ret_brk || new_brk < high_brk) { - errno = ENOMEM; - return ((void *)-1); - } - - brk_result = brk((void *)new_brk); - - if (brk_result != 0) - return ((void *)-1); - - if (actual_size != NULL) - *actual_size = (new_brk - ret_brk); - return ((void *)ret_brk); -} - /* * Try to extend src with [pos, pos + size). * @@ -234,7 +175,7 @@ vmem_sbrk_alloc(vmem_t *src, size_t size, int vmflags) (ret = vmem_sbrk_tryfail(src, size, vmflags)) != NULL) return (ret); - buf_size = MAX(size, MIN_ALLOC); + buf_size = MAX(size, vmem_sbrk_minalloc); /* * buf_size gets overwritten with the actual allocated size @@ -293,7 +234,6 @@ vmem_sbrk_arena(vmem_alloc_t **a_out, vmem_free_t **f_out) if (heap_size <= real_pagesize) { heap_size = real_pagesize; } else { -#ifdef MHA_MAPSIZE_BSSBRK struct memcntl_mha mha; mha.mha_cmd = MHA_MAPSIZE_BSSBRK; mha.mha_flags = 0; @@ -305,12 +245,14 @@ vmem_sbrk_arena(vmem_alloc_t **a_out, vmem_free_t **f_out) "0x%p\n", heap_size); heap_size = real_pagesize; } -#else - heap_size = real_pagesize; -#endif } vmem_sbrk_pagesize = heap_size; + /* validate vmem_sbrk_minalloc */ + if (vmem_sbrk_minalloc < VMEM_SBRK_MINALLOC) + vmem_sbrk_minalloc = VMEM_SBRK_MINALLOC; + vmem_sbrk_minalloc = P2ROUNDUP(vmem_sbrk_minalloc, heap_size); + sbrk_heap = vmem_init("sbrk_top", real_pagesize, vmem_sbrk_alloc, vmem_free, "sbrk_heap", NULL, 0, real_pagesize, diff --git a/zfs/lib/libumem/vmem_stand.c b/zfs/lib/libumem/vmem_stand.c new file mode 100644 index 000000000..da19043df --- /dev/null +++ b/zfs/lib/libumem/vmem_stand.c @@ -0,0 +1,164 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Standalone-specific vmem routines + * + * The standalone allocator operates on a pre-existing blob of memory, the + * location and dimensions of which are set using vmem_stand_setsize(). We + * then hand out CHUNKSIZE-sized pieces of this blob, until we run out. + */ + +#define DEF_CHUNKSIZE (64 * 1024) /* 64K */ + +#define DEF_NREGIONS 2 + +#include +#include +#include +#include +#include +#include + +#include "vmem_base.h" +#include "misc.h" + +static vmem_t *stand_heap; + +static size_t stand_chunksize; + +typedef struct stand_region { + caddr_t sr_base; + caddr_t sr_curtop; + size_t sr_left; +} stand_region_t; + +static stand_region_t stand_regions[DEF_NREGIONS]; +static int stand_nregions; + +extern void membar_producer(void); + +void +vmem_stand_init(void) +{ + stand_chunksize = MAX(DEF_CHUNKSIZE, pagesize); + + stand_nregions = 0; +} + +int +vmem_stand_add(caddr_t base, size_t len) +{ + stand_region_t *sr = &stand_regions[stand_nregions]; + + ASSERT(pagesize != 0); + + if (stand_nregions == DEF_NREGIONS) { + errno = ENOSPC; + return (-1); /* we don't have room -- throw it back */ + } + + /* + * We guarantee that only one call to `vmem_stand_add' will be + * active at a time, but we can't ensure that the allocator won't be + * in use while this function is being called. As such, we have to + * ensure that sr is populated and visible to other processors before + * allowing the allocator to access the new region. + */ + sr->sr_base = base; + sr->sr_curtop = (caddr_t)P2ROUNDUP((ulong_t)base, stand_chunksize); + sr->sr_left = P2ALIGN(len - (size_t)(sr->sr_curtop - sr->sr_base), + stand_chunksize); + membar_producer(); + + stand_nregions++; + + return (0); +} + +static void * +stand_parent_alloc(vmem_t *src, size_t size, int vmflags) +{ + int old_errno = errno; + stand_region_t *sr; + size_t chksize; + void *ret; + int i; + + if ((ret = vmem_alloc(src, size, VM_NOSLEEP)) != NULL) { + errno = old_errno; + return (ret); + } + + /* We need to allocate another chunk */ + chksize = roundup(size, stand_chunksize); + + for (sr = stand_regions, i = 0; i < stand_nregions; i++, sr++) { + if (sr->sr_left >= chksize) + break; + } + + if (i == stand_nregions) { + /* + * We don't have enough in any of our regions to satisfy the + * request. + */ + errno = old_errno; + return (NULL); + } + + if ((ret = _vmem_extend_alloc(src, sr->sr_curtop, chksize, size, + vmflags)) == NULL) { + errno = old_errno; + return (NULL); + } + + bzero(sr->sr_curtop, chksize); + + sr->sr_curtop += chksize; + sr->sr_left -= chksize; + + return (ret); +} + +vmem_t * +vmem_stand_arena(vmem_alloc_t **a_out, vmem_free_t **f_out) +{ + ASSERT(stand_nregions == 1); + + stand_heap = vmem_init("stand_parent", stand_chunksize, + stand_parent_alloc, vmem_free, + "stand_heap", NULL, 0, pagesize, vmem_alloc, vmem_free); + + if (a_out != NULL) + *a_out = vmem_alloc; + if (f_out != NULL) + *f_out = vmem_free; + + return (stand_heap); +} diff --git a/zfs/lib/libuutil/include/libuutil.h b/zfs/lib/libuutil/include/libuutil.h index 076be7605..ccd46b977 100644 --- a/zfs/lib/libuutil/include/libuutil.h +++ b/zfs/lib/libuutil/include/libuutil.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _LIBUUTIL_H #define _LIBUUTIL_H - - #include #include @@ -148,6 +145,7 @@ extern int uu_open_tmp(const char *dir, uint_t uflags); /*PRINTFLIKE1*/ extern char *uu_msprintf(const char *format, ...); extern void *uu_zalloc(size_t); +extern char *uu_strdup(const char *); extern void uu_free(void *); /* diff --git a/zfs/lib/libuutil/include/libuutil_common.h b/zfs/lib/libuutil/include/libuutil_common.h index 8a0f1840e..9ebaaedfd 100644 --- a/zfs/lib/libuutil/include/libuutil_common.h +++ b/zfs/lib/libuutil/include/libuutil_common.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,22 +20,14 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _LIBUUTIL_COMMON_H #define _LIBUUTIL_COMMON_H - - -/* - * We don't bind to the internal libc interfaces if this is a - * native build. - */ -#ifndef NATIVE_BUILD -#include "c_synonyms.h" -#endif +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libuutil/include/libuutil_impl.h b/zfs/lib/libuutil/include/libuutil_impl.h index f978b475e..9466e5974 100644 --- a/zfs/lib/libuutil/include/libuutil_impl.h +++ b/zfs/lib/libuutil/include/libuutil_impl.h @@ -27,7 +27,7 @@ #ifndef _LIBUUTIL_IMPL_H #define _LIBUUTIL_IMPL_H - +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -40,11 +40,11 @@ extern "C" { #endif void uu_set_error(uint_t); - +#pragma rarely_called(uu_set_error) /*PRINTFLIKE1*/ void uu_panic(const char *format, ...); - +#pragma rarely_called(uu_panic) struct uu_dprintf { char *uud_name; diff --git a/zfs/lib/libuutil/uu_alloc.c b/zfs/lib/libuutil/uu_alloc.c index 53f3496bf..05d862287 100644 --- a/zfs/lib/libuutil/uu_alloc.c +++ b/zfs/lib/libuutil/uu_alloc.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - - #include "libuutil_common.h" #include @@ -54,6 +51,22 @@ uu_free(void *p) free(p); } +char * +uu_strdup(const char *str) +{ + char *buf = NULL; + + if (str != NULL) { + size_t sz; + + sz = strlen(str) + 1; + buf = uu_zalloc(sz); + if (buf != NULL) + (void) memcpy(buf, str, sz); + } + return (buf); +} + char * uu_msprintf(const char *format, ...) { diff --git a/zfs/lib/libuutil/uu_avl.c b/zfs/lib/libuutil/uu_avl.c index 348bde3b1..308e9208f 100644 --- a/zfs/lib/libuutil/uu_avl.c +++ b/zfs/lib/libuutil/uu_avl.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include "libuutil_common.h" @@ -120,7 +120,8 @@ uu_avl_pool_destroy(uu_avl_pool_t *pp) UU_PTR_ENCODE(&pp->uap_null_avl)) { uu_panic("uu_avl_pool_destroy: Pool \"%.*s\" (%p) has " "outstanding avls, or is corrupt.\n", - sizeof (pp->uap_name), pp->uap_name, pp); + (int)sizeof (pp->uap_name), pp->uap_name, + (void *)pp); } } (void) pthread_mutex_lock(&uu_apool_list_lock); @@ -142,14 +143,14 @@ uu_avl_node_init(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp) if (offset + sizeof (*np) > pp->uap_objsize) { uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): " "offset %ld doesn't fit in object (size %ld)\n", - base, np, pp, pp->uap_name, offset, - pp->uap_objsize); + base, (void *)np, (void *)pp, pp->uap_name, + (long)offset, (long)pp->uap_objsize); } if (offset != pp->uap_nodeoffset) { uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): " "offset %ld doesn't match pool's offset (%ld)\n", - base, np, pp, pp->uap_name, offset, - pp->uap_objsize); + base, (void *)np, (void *)pp, pp->uap_name, + (long)offset, (long)pp->uap_objsize); } } @@ -166,12 +167,12 @@ uu_avl_node_fini(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp) if (na[0] == DEAD_MARKER && na[1] == DEAD_MARKER) { uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): " "node already finied\n", - base, np, pp, pp->uap_name); + base, (void *)np, (void *)pp, pp->uap_name); } if (na[0] != POOL_TO_MARKER(pp) || na[1] != 0) { uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): " "node corrupt, in tree, or in different pool\n", - base, np, pp, pp->uap_name); + base, (void *)np, (void *)pp, pp->uap_name); } } @@ -251,12 +252,13 @@ uu_avl_destroy(uu_avl_t *ap) if (ap->ua_debug) { if (avl_numnodes(&ap->ua_tree) != 0) { - uu_panic("uu_avl_destroy(%p): tree not empty\n", ap); + uu_panic("uu_avl_destroy(%p): tree not empty\n", + (void *)ap); } if (ap->ua_null_walk.uaw_next != &ap->ua_null_walk || ap->ua_null_walk.uaw_prev != &ap->ua_null_walk) { uu_panic("uu_avl_destroy(%p): outstanding walkers\n", - ap); + (void *)ap); } } (void) pthread_mutex_lock(&pp->uap_lock); @@ -441,7 +443,7 @@ uu_avl_remove(uu_avl_t *ap, void *elem) (void) _avl_walk_advance(wp, ap); } else if (wp->uaw_next_result != NULL) { uu_panic("uu_avl_remove(%p, %p): active non-robust " - "walker\n", ap, elem); + "walker\n", (void *)ap, elem); } } @@ -497,19 +499,19 @@ uu_avl_insert(uu_avl_t *ap, void *elem, uu_avl_index_t idx) if (na[1] != 0) uu_panic("uu_avl_insert(%p, %p, %p): node already " "in tree, or corrupt\n", - ap, elem, idx); + (void *)ap, elem, (void *)idx); if (na[0] == 0) uu_panic("uu_avl_insert(%p, %p, %p): node not " "initialized\n", - ap, elem, idx); + (void *)ap, elem, (void *)idx); if (na[0] != POOL_TO_MARKER(pp)) uu_panic("uu_avl_insert(%p, %p, %p): node from " "other pool, or corrupt\n", - ap, elem, idx); + (void *)ap, elem, (void *)idx); if (!INDEX_VALID(ap, idx)) uu_panic("uu_avl_insert(%p, %p, %p): %s\n", - ap, elem, idx, + (void *)ap, elem, (void *)idx, INDEX_CHECK(idx)? "outdated index" : "invalid index"); @@ -526,8 +528,8 @@ uu_avl_nearest_next(uu_avl_t *ap, uu_avl_index_t idx) { if (ap->ua_debug && !INDEX_VALID(ap, idx)) uu_panic("uu_avl_nearest_next(%p, %p): %s\n", - ap, idx, INDEX_CHECK(idx)? "outdated index" : - "invalid index"); + (void *)ap, (void *)idx, INDEX_CHECK(idx)? + "outdated index" : "invalid index"); return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_AFTER)); } @@ -536,8 +538,8 @@ uu_avl_nearest_prev(uu_avl_t *ap, uu_avl_index_t idx) { if (ap->ua_debug && !INDEX_VALID(ap, idx)) uu_panic("uu_avl_nearest_prev(%p, %p): %s\n", - ap, idx, INDEX_CHECK(idx)? "outdated index" : - "invalid index"); + (void *)ap, (void *)idx, INDEX_CHECK(idx)? + "outdated index" : "invalid index"); return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_BEFORE)); } diff --git a/zfs/lib/libuutil/uu_dprintf.c b/zfs/lib/libuutil/uu_dprintf.c index 5d5fb84a8..5b990a52b 100644 --- a/zfs/lib/libuutil/uu_dprintf.c +++ b/zfs/lib/libuutil/uu_dprintf.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include "libuutil_common.h" diff --git a/zfs/lib/libuutil/uu_ident.c b/zfs/lib/libuutil/uu_ident.c index 382139316..9a643845f 100644 --- a/zfs/lib/libuutil/uu_ident.c +++ b/zfs/lib/libuutil/uu_ident.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include "libuutil_common.h" diff --git a/zfs/lib/libuutil/uu_list.c b/zfs/lib/libuutil/uu_list.c index d02224eb8..35c7ba800 100644 --- a/zfs/lib/libuutil/uu_list.c +++ b/zfs/lib/libuutil/uu_list.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include "libuutil_common.h" @@ -117,7 +116,8 @@ uu_list_pool_destroy(uu_list_pool_t *pp) UU_PTR_ENCODE(&pp->ulp_null_list)) { uu_panic("uu_list_pool_destroy: Pool \"%.*s\" (%p) has " "outstanding lists, or is corrupt.\n", - sizeof (pp->ulp_name), pp->ulp_name, pp); + (int)sizeof (pp->ulp_name), pp->ulp_name, + (void *)pp); } } (void) pthread_mutex_lock(&uu_lpool_list_lock); @@ -139,14 +139,14 @@ uu_list_node_init(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp) if (offset + sizeof (*np) > pp->ulp_objsize) { uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): " "offset %ld doesn't fit in object (size %ld)\n", - base, np, pp, pp->ulp_name, offset, - pp->ulp_objsize); + base, (void *)np, (void *)pp, pp->ulp_name, + (long)offset, (long)pp->ulp_objsize); } if (offset != pp->ulp_nodeoffset) { uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): " "offset %ld doesn't match pool's offset (%ld)\n", - base, np, pp, pp->ulp_name, offset, - pp->ulp_objsize); + base, (void *)np, (void *)pp, pp->ulp_name, + (long)offset, (long)pp->ulp_objsize); } } np->uln_next = POOL_TO_MARKER(pp); @@ -163,13 +163,13 @@ uu_list_node_fini(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp) np->uln_prev == NULL) { uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): " "node already finied\n", - base, np_arg, pp, pp->ulp_name); + base, (void *)np_arg, (void *)pp, pp->ulp_name); } if (np->uln_next != POOL_TO_MARKER(pp) || np->uln_prev != NULL) { uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): " "node corrupt or on list\n", - base, np_arg, pp, pp->ulp_name); + base, (void *)np_arg, (void *)pp, pp->ulp_name); } } np->uln_next = NULL; @@ -190,7 +190,7 @@ uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags) if (pp->ulp_debug) uu_panic("uu_list_create(%p, ...): requested " "UU_LIST_SORTED, but pool has no comparison func\n", - pp); + (void *)pp); uu_set_error(UU_ERROR_NOT_SUPPORTED); return (NULL); } @@ -236,16 +236,16 @@ uu_list_destroy(uu_list_t *lp) if (lp->ul_null_node.uln_next != &lp->ul_null_node || lp->ul_null_node.uln_prev != &lp->ul_null_node) { uu_panic("uu_list_destroy(%p): list not empty\n", - lp); + (void *)lp); } if (lp->ul_numnodes != 0) { uu_panic("uu_list_destroy(%p): numnodes is nonzero, " - "but list is empty\n", lp); + "but list is empty\n", (void *)lp); } if (lp->ul_null_walk.ulw_next != &lp->ul_null_walk || lp->ul_null_walk.ulw_prev != &lp->ul_null_walk) { uu_panic("uu_list_destroy(%p): outstanding walkers\n", - lp); + (void *)lp); } } @@ -266,13 +266,14 @@ list_insert(uu_list_t *lp, uu_list_node_impl_t *np, uu_list_node_impl_t *prev, if (lp->ul_debug) { if (next->uln_prev != prev || prev->uln_next != next) uu_panic("insert(%p): internal error: %p and %p not " - "neighbors\n", lp, next, prev); + "neighbors\n", (void *)lp, (void *)next, + (void *)prev); if (np->uln_next != POOL_TO_MARKER(lp->ul_pool) || np->uln_prev != NULL) { uu_panic("insert(%p): elem %p node %p corrupt, " "not initialized, or already in a list.\n", - lp, NODE_TO_ELEM(lp, np), np); + (void *)lp, NODE_TO_ELEM(lp, np), (void *)np); } /* * invalidate outstanding uu_list_index_ts. @@ -299,12 +300,12 @@ uu_list_insert(uu_list_t *lp, void *elem, uu_list_index_t idx) if (lp->ul_debug) { if (!INDEX_VALID(lp, idx)) uu_panic("uu_list_insert(%p, %p, %p): %s\n", - lp, elem, idx, + (void *)lp, elem, (void *)idx, INDEX_CHECK(idx)? "outdated index" : "invalid index"); if (np->uln_prev == NULL) uu_panic("uu_list_insert(%p, %p, %p): out-of-date " - "index\n", lp, elem, idx); + "index\n", (void *)lp, elem, (void *)idx); } list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np); @@ -354,11 +355,12 @@ uu_list_nearest_next(uu_list_t *lp, uu_list_index_t idx) if (lp->ul_debug) { if (!INDEX_VALID(lp, idx)) uu_panic("uu_list_nearest_next(%p, %p): %s\n", - lp, idx, INDEX_CHECK(idx)? "outdated index" : + (void *)lp, (void *)idx, + INDEX_CHECK(idx)? "outdated index" : "invalid index"); if (np->uln_prev == NULL) uu_panic("uu_list_nearest_next(%p, %p): out-of-date " - "index\n", lp, idx); + "index\n", (void *)lp, (void *)idx); } if (np == &lp->ul_null_node) @@ -378,11 +380,11 @@ uu_list_nearest_prev(uu_list_t *lp, uu_list_index_t idx) if (lp->ul_debug) { if (!INDEX_VALID(lp, idx)) uu_panic("uu_list_nearest_prev(%p, %p): %s\n", - lp, idx, INDEX_CHECK(idx)? "outdated index" : - "invalid index"); + (void *)lp, (void *)idx, INDEX_CHECK(idx)? + "outdated index" : "invalid index"); if (np->uln_prev == NULL) uu_panic("uu_list_nearest_prev(%p, %p): out-of-date " - "index\n", lp, idx); + "index\n", (void *)lp, (void *)idx); } if ((np = np->uln_prev) == &lp->ul_null_node) @@ -409,6 +411,11 @@ list_walk_init(uu_list_walk_t *wp, uu_list_t *lp, uint32_t flags) wp->ulw_next_result = lp->ul_null_node.uln_prev; if (lp->ul_debug || robust) { + /* + * Add this walker to the list's list of walkers so + * uu_list_remove() can advance us if somebody tries to + * remove ulw_next_result. + */ wp->ulw_next = next = &lp->ul_null_walk; wp->ulw_prev = prev = next->ulw_prev; next->ulw_prev = wp; @@ -538,7 +545,7 @@ uu_list_remove(uu_list_t *lp, void *elem) if (lp->ul_debug) { if (np->uln_prev == NULL) uu_panic("uu_list_remove(%p, %p): elem not on list\n", - lp, elem); + (void *)lp, elem); /* * invalidate outstanding uu_list_index_ts. */ @@ -556,7 +563,7 @@ uu_list_remove(uu_list_t *lp, void *elem) (void) list_walk_advance(wp, lp); } else if (wp->ulw_next_result != NULL) { uu_panic("uu_list_remove(%p, %p): active non-robust " - "walker\n", lp, elem); + "walker\n", (void *)lp, elem); } } @@ -578,8 +585,8 @@ uu_list_teardown(uu_list_t *lp, void **cookie) * XXX: disable list modification until list is empty */ if (lp->ul_debug && *cookie != NULL) - uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n", lp, - cookie); + uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n", + (void *)lp, (void *)cookie); ep = uu_list_first(lp); if (ep) @@ -599,12 +606,12 @@ uu_list_insert_before(uu_list_t *lp, void *target, void *elem) if (np->uln_prev == NULL) uu_panic("uu_list_insert_before(%p, %p, %p): %p is " "not currently on a list\n", - lp, target, elem, target); + (void *)lp, target, elem, target); } if (lp->ul_sorted) { if (lp->ul_debug) uu_panic("uu_list_insert_before(%p, ...): list is " - "UU_LIST_SORTED\n", lp); + "UU_LIST_SORTED\n", (void *)lp); uu_set_error(UU_ERROR_NOT_SUPPORTED); return (-1); } @@ -625,12 +632,12 @@ uu_list_insert_after(uu_list_t *lp, void *target, void *elem) if (np->uln_prev == NULL) uu_panic("uu_list_insert_after(%p, %p, %p): %p is " "not currently on a list\n", - lp, target, elem, target); + (void *)lp, target, elem, target); } if (lp->ul_sorted) { if (lp->ul_debug) uu_panic("uu_list_insert_after(%p, ...): list is " - "UU_LIST_SORTED\n", lp); + "UU_LIST_SORTED\n", (void *)lp); uu_set_error(UU_ERROR_NOT_SUPPORTED); return (-1); } diff --git a/zfs/lib/libuutil/uu_misc.c b/zfs/lib/libuutil/uu_misc.c index 0ead166e7..74ec177c1 100644 --- a/zfs/lib/libuutil/uu_misc.c +++ b/zfs/lib/libuutil/uu_misc.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include "libuutil_common.h" diff --git a/zfs/lib/libuutil/uu_open.c b/zfs/lib/libuutil/uu_open.c index cf5c5450b..7256662e3 100644 --- a/zfs/lib/libuutil/uu_open.c +++ b/zfs/lib/libuutil/uu_open.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include "libuutil_common.h" diff --git a/zfs/lib/libuutil/uu_pname.c b/zfs/lib/libuutil/uu_pname.c index a6a0f2266..3307a26dc 100644 --- a/zfs/lib/libuutil/uu_pname.c +++ b/zfs/lib/libuutil/uu_pname.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include "libuutil_common.h" diff --git a/zfs/lib/libuutil/uu_strtoint.c b/zfs/lib/libuutil/uu_strtoint.c index 494e0a5b9..8fd114836 100644 --- a/zfs/lib/libuutil/uu_strtoint.c +++ b/zfs/lib/libuutil/uu_strtoint.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ - +#pragma ident "%Z%%M% %I% %E% SMI" #include "libuutil_common.h" diff --git a/zfs/lib/libzcommon/compress.c b/zfs/lib/libzcommon/compress.c deleted file mode 100644 index 4bf55ba16..000000000 --- a/zfs/lib/libzcommon/compress.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - - - -/* - * NOTE: this file is compiled into the kernel, cprboot, and savecore. - * Therefore it must compile in kernel, boot, and userland source context; - * so if you ever change this code, avoid references to external symbols. - * - * This compression algorithm is a derivative of LZRW1, which I'll call - * LZJB in the classic LZ* spirit. All LZ* (Lempel-Ziv) algorithms are - * based on the same basic principle: when a "phrase" (sequences of bytes) - * is repeated in a data stream, we can save space by storing a reference to - * the previous instance of that phrase (a "copy item") rather than storing - * the phrase itself (a "literal item"). The compressor remembers phrases - * in a simple hash table (the "Lempel history") that maps three-character - * sequences (the minimum match) to the addresses where they were last seen. - * - * A copy item must encode both the length and the location of the matching - * phrase so that decompress() can reconstruct the original data stream. - * For example, here's how we'd encode "yadda yadda yadda, blah blah blah" - * (with "_" replacing spaces for readability): - * - * Original: - * - * y a d d a _ y a d d a _ y a d d a , _ b l a h _ b l a h _ b l a h - * - * Compressed: - * - * y a d d a _ 6 11 , _ b l a h 5 10 - * - * In the compressed output, the "6 11" simply means "to get the original - * data, execute memmove(ptr, ptr - 6, 11)". Note that in this example, - * the match at "6 11" actually extends beyond the current location and - * overlaps it. That's OK; like memmove(), decompress() handles overlap. - * - * There's still one more thing decompress() needs to know, which is how to - * distinguish literal items from copy items. We encode this information - * in an 8-bit bitmap that precedes each 8 items of output; if the Nth bit - * is set, then the Nth item is a copy item. Thus the full encoding for - * the example above would be: - * - * 0x40 y a d d a _ 6 11 , 0x20 _ b l a h 5 10 - * - * Finally, the "6 11" isn't really encoded as the two byte values 6 and 11 - * in the output stream because, empirically, we get better compression by - * dedicating more bits to offset, fewer to match length. LZJB uses 6 bits - * to encode the match length, 10 bits to encode the offset. Since copy-item - * encoding consumes 2 bytes, we don't generate copy items unless the match - * length is at least 3; therefore, we can store (length - 3) in the 6-bit - * match length field, which extends the maximum match from 63 to 66 bytes. - * Thus the 2-byte encoding for a copy item is as follows: - * - * byte[0] = ((length - 3) << 2) | (offset >> 8); - * byte[1] = (uint8_t)offset; - * - * In our example above, an offset of 6 with length 11 would be encoded as: - * - * byte[0] = ((11 - 3) << 2) | (6 >> 8) = 0x20 - * byte[1] = (uint8_t)6 = 0x6 - * - * Similarly, an offset of 5 with length 10 would be encoded as: - * - * byte[0] = ((10 - 3) << 2) | (5 >> 8) = 0x1c - * byte[1] = (uint8_t)5 = 0x5 - * - * Putting it all together, the actual LZJB output for our example is: - * - * 0x40 y a d d a _ 0x2006 , 0x20 _ b l a h 0x1c05 - * - * The main differences between LZRW1 and LZJB are as follows: - * - * (1) LZRW1 is sloppy about buffer overruns. LZJB never reads past the - * end of its input, and never writes past the end of its output. - * - * (2) LZJB allows a maximum match length of 66 (vs. 18 for LZRW1), with - * the trade-off being a shorter look-behind (1K vs. 4K for LZRW1). - * - * (3) LZJB records only the low-order 16 bits of pointers in the Lempel - * history (which is all we need since the maximum look-behind is 1K), - * and uses only 256 hash entries (vs. 4096 for LZRW1). This makes - * the compression hash small enough to allocate on the stack, which - * solves two problems: (1) it saves 64K of kernel/cprboot memory, - * and (2) it makes the code MT-safe without any locking, since we - * don't have multiple threads sharing a common hash table. - * - * (4) LZJB is faster at both compression and decompression, has a - * better compression ratio, and is somewhat simpler than LZRW1. - * - * Finally, note that LZJB is non-deterministic: given the same input, - * two calls to compress() may produce different output. This is a - * general characteristic of most Lempel-Ziv derivatives because there's - * no need to initialize the Lempel history; not doing so saves time. - */ - -#include - -#define MATCH_BITS 6 -#define MATCH_MIN 3 -#define MATCH_MAX ((1 << MATCH_BITS) + (MATCH_MIN - 1)) -#define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1) -#define LEMPEL_SIZE 256 - -size_t -compress(void *s_start, void *d_start, size_t s_len) -{ - uchar_t *src = s_start; - uchar_t *dst = d_start; - uchar_t *cpy, *copymap; - int copymask = 1 << (NBBY - 1); - int mlen, offset; - uint16_t *hp; - uint16_t lempel[LEMPEL_SIZE]; /* uninitialized; see above */ - - while (src < (uchar_t *)s_start + s_len) { - if ((copymask <<= 1) == (1 << NBBY)) { - if (dst >= (uchar_t *)d_start + s_len - 1 - 2 * NBBY) { - mlen = s_len; - for (src = s_start, dst = d_start; mlen; mlen--) - *dst++ = *src++; - return (s_len); - } - copymask = 1; - copymap = dst; - *dst++ = 0; - } - if (src > (uchar_t *)s_start + s_len - MATCH_MAX) { - *dst++ = *src++; - continue; - } - hp = &lempel[((src[0] + 13) ^ (src[1] - 13) ^ src[2]) & - (LEMPEL_SIZE - 1)]; - offset = (intptr_t)(src - *hp) & OFFSET_MASK; - *hp = (uint16_t)(uintptr_t)src; - cpy = src - offset; - if (cpy >= (uchar_t *)s_start && cpy != src && - src[0] == cpy[0] && src[1] == cpy[1] && src[2] == cpy[2]) { - *copymap |= copymask; - for (mlen = MATCH_MIN; mlen < MATCH_MAX; mlen++) - if (src[mlen] != cpy[mlen]) - break; - *dst++ = ((mlen - MATCH_MIN) << (NBBY - MATCH_BITS)) | - (offset >> NBBY); - *dst++ = (uchar_t)offset; - src += mlen; - } else { - *dst++ = *src++; - } - } - return (dst - (uchar_t *)d_start); -} - -size_t -decompress(void *s_start, void *d_start, size_t s_len, size_t d_len) -{ - uchar_t *src = s_start; - uchar_t *dst = d_start; - uchar_t *s_end = (uchar_t *)s_start + s_len; - uchar_t *d_end = (uchar_t *)d_start + d_len; - uchar_t *cpy, copymap; - int copymask = 1 << (NBBY - 1); - - if (s_len >= d_len) { - size_t d_rem = d_len; - while (d_rem-- != 0) - *dst++ = *src++; - return (d_len); - } - - while (src < s_end && dst < d_end) { - if ((copymask <<= 1) == (1 << NBBY)) { - copymask = 1; - copymap = *src++; - } - if (copymap & copymask) { - int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN; - int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK; - src += 2; - if ((cpy = dst - offset) >= (uchar_t *)d_start) - while (--mlen >= 0 && dst < d_end) - *dst++ = *cpy++; - else - /* - * offset before start of destination buffer - * indicates corrupt source data - */ - return (dst - (uchar_t *)d_start); - } else { - *dst++ = *src++; - } - } - return (dst - (uchar_t *)d_start); -} - -uint32_t -checksum32(void *cp_arg, size_t length) -{ - uchar_t *cp, *ep; - uint32_t sum = 0; - - for (cp = cp_arg, ep = cp + length; cp < ep; cp++) - sum = ((sum >> 1) | (sum << 31)) + *cp; - return (sum); -} diff --git a/zfs/lib/libzcommon/include/sys/compress.h b/zfs/lib/libzcommon/include/sys/compress.h deleted file mode 100644 index ca7159dc3..000000000 --- a/zfs/lib/libzcommon/include/sys/compress.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_COMPRESS_H -#define _SYS_COMPRESS_H - - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern size_t compress(void *, void *, size_t); -extern size_t decompress(void *, void *, size_t, size_t); -extern uint32_t checksum32(void *, size_t); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_COMPRESS_H */ diff --git a/zfs/lib/libzcommon/include/sys/dmu_traverse.h b/zfs/lib/libzcommon/include/sys/dmu_traverse.h deleted file mode 100644 index 827050527..000000000 --- a/zfs/lib/libzcommon/include/sys/dmu_traverse.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DMU_TRAVERSE_H -#define _SYS_DMU_TRAVERSE_H - -#pragma ident "@(#)dmu_traverse.h 1.4 08/04/01 SMI" - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define ADVANCE_POST 0 /* post-order traversal */ -#define ADVANCE_PRE 0x01 /* pre-order traversal */ -#define ADVANCE_PRUNE 0x02 /* prune by prev snapshot birth time */ -#define ADVANCE_DATA 0x04 /* read user data blocks */ -#define ADVANCE_HOLES 0x08 /* visit holes */ -#define ADVANCE_ZIL 0x10 /* visit intent log blocks */ -#define ADVANCE_NOLOCK 0x20 /* Don't grab SPA sync lock */ - -#define ZB_NO_LEVEL -2 -#define ZB_MAXLEVEL 32 /* Next power of 2 >= DN_MAX_LEVELS */ -#define ZB_MAXBLKID (1ULL << 62) -#define ZB_MAXOBJSET (1ULL << 62) -#define ZB_MAXOBJECT (1ULL << 62) - -#define ZB_MOS_CACHE 0 -#define ZB_MDN_CACHE 1 -#define ZB_DN_CACHE 2 -#define ZB_DEPTH 3 - -typedef struct zseg { - uint64_t seg_mintxg; - uint64_t seg_maxtxg; - zbookmark_t seg_start; - zbookmark_t seg_end; - list_node_t seg_node; -} zseg_t; - -typedef struct traverse_blk_cache { - zbookmark_t bc_bookmark; - blkptr_t bc_blkptr; - void *bc_data; - dnode_phys_t *bc_dnode; - int bc_errno; - int bc_pad1; - uint64_t bc_pad2; -} traverse_blk_cache_t; - -typedef int (blkptr_cb_t)(traverse_blk_cache_t *bc, spa_t *spa, void *arg); - -struct traverse_handle { - spa_t *th_spa; - blkptr_cb_t *th_func; - void *th_arg; - uint16_t th_advance; - uint16_t th_locked; - int th_zio_flags; - list_t th_seglist; - traverse_blk_cache_t th_cache[ZB_DEPTH][ZB_MAXLEVEL]; - traverse_blk_cache_t th_zil_cache; - uint64_t th_hits; - uint64_t th_arc_hits; - uint64_t th_reads; - uint64_t th_callbacks; - uint64_t th_syncs; - uint64_t th_restarts; - zbookmark_t th_noread; - zbookmark_t th_lastcb; -}; - -int traverse_dsl_dataset(struct dsl_dataset *ds, uint64_t txg_start, - int advance, blkptr_cb_t func, void *arg); -int traverse_zvol(objset_t *os, int advance, blkptr_cb_t func, void *arg); - -traverse_handle_t *traverse_init(spa_t *spa, blkptr_cb_t *func, void *arg, - int advance, int zio_flags); -void traverse_fini(traverse_handle_t *th); - -void traverse_add_dnode(traverse_handle_t *th, - uint64_t mintxg, uint64_t maxtxg, uint64_t objset, uint64_t object); -void traverse_add_objset(traverse_handle_t *th, - uint64_t mintxg, uint64_t maxtxg, uint64_t objset); -void traverse_add_pool(traverse_handle_t *th, uint64_t mintxg, uint64_t maxtxg); - -int traverse_more(traverse_handle_t *th); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_DMU_TRAVERSE_H */ diff --git a/zfs/lib/libzcommon/include/sys/fm/fs/zfs.h b/zfs/lib/libzcommon/include/sys/fm/fs/zfs.h index d7aa07221..66ca9c5d7 100644 --- a/zfs/lib/libzcommon/include/sys/fm/fs/zfs.h +++ b/zfs/lib/libzcommon/include/sys/fm/fs/zfs.h @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_FM_FS_ZFS_H #define _SYS_FM_FS_ZFS_H -#pragma ident "@(#)zfs.h 1.2 07/06/07 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { @@ -45,8 +45,12 @@ extern "C" { #define FM_EREPORT_ZFS_DEVICE_BAD_GUID_SUM "vdev.bad_guid_sum" #define FM_EREPORT_ZFS_DEVICE_TOO_SMALL "vdev.too_small" #define FM_EREPORT_ZFS_DEVICE_BAD_LABEL "vdev.bad_label" +#define FM_EREPORT_ZFS_IO_FAILURE "io_failure" +#define FM_EREPORT_ZFS_PROBE_FAILURE "probe_failure" +#define FM_EREPORT_ZFS_LOG_REPLAY "log_replay" #define FM_EREPORT_PAYLOAD_ZFS_POOL "pool" +#define FM_EREPORT_PAYLOAD_ZFS_POOL_FAILMODE "pool_failmode" #define FM_EREPORT_PAYLOAD_ZFS_POOL_GUID "pool_guid" #define FM_EREPORT_PAYLOAD_ZFS_POOL_CONTEXT "pool_context" #define FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID "vdev_guid" @@ -66,7 +70,10 @@ extern "C" { #define FM_EREPORT_PAYLOAD_ZFS_ZIO_SIZE "zio_size" #define FM_EREPORT_PAYLOAD_ZFS_PREV_STATE "prev_state" -#define FM_RESOURCE_OK "ok" +#define FM_EREPORT_FAILMODE_WAIT "wait" +#define FM_EREPORT_FAILMODE_CONTINUE "continue" +#define FM_EREPORT_FAILMODE_PANIC "panic" + #define FM_RESOURCE_REMOVED "removed" #define FM_RESOURCE_AUTOREPLACE "autoreplace" diff --git a/zfs/lib/libzcommon/include/sys/fs/zfs.h b/zfs/lib/libzcommon/include/sys/fs/zfs.h index 7f2aa55d3..95f04d842 100644 --- a/zfs/lib/libzcommon/include/sys/fs/zfs.h +++ b/zfs/lib/libzcommon/include/sys/fs/zfs.h @@ -26,8 +26,6 @@ #ifndef _SYS_FS_ZFS_H #define _SYS_FS_ZFS_H -#pragma ident "@(#)zfs.h 1.44 08/04/09 SMI" - #ifdef __cplusplus extern "C" { #endif @@ -100,12 +98,19 @@ typedef enum { ZFS_PROP_SHARESMB, ZFS_PROP_REFQUOTA, ZFS_PROP_REFRESERVATION, + ZFS_PROP_GUID, + ZFS_PROP_PRIMARYCACHE, + ZFS_PROP_SECONDARYCACHE, + ZFS_PROP_USEDSNAP, + ZFS_PROP_USEDDS, + ZFS_PROP_USEDCHILD, + ZFS_PROP_USEDREFRESERV, ZFS_NUM_PROPS } zfs_prop_t; /* * Pool properties are identified by these constants and must be added to the - * end of this list to ensure that external conumsers are not affected + * end of this list to ensure that external consumers are not affected * by the change. If you make any changes to this list, be sure to update * the property table in usr/src/common/zfs/zpool_prop.c. */ @@ -124,6 +129,7 @@ typedef enum { ZPOOL_PROP_AUTOREPLACE, ZPOOL_PROP_CACHEFILE, ZPOOL_PROP_FAILUREMODE, + ZPOOL_PROP_LISTSNAPS, ZPOOL_NUM_PROPS } zpool_prop_t; @@ -145,6 +151,13 @@ typedef enum { typedef int (*zprop_func)(int, void *); +/* + * Properties to be set on the root file system of a new pool + * are stuffed into their own nvlist, which is then included in + * the properties nvlist with the pool properties. + */ +#define ZPOOL_ROOTFS_PROPS "root-props-nvl" + /* * Dataset property functions shared between libzfs and kernel. */ @@ -158,7 +171,7 @@ zfs_prop_t zfs_name_to_prop(const char *); boolean_t zfs_prop_user(const char *); int zfs_prop_index_to_string(zfs_prop_t, uint64_t, const char **); int zfs_prop_string_to_index(zfs_prop_t, const char *, uint64_t *); -int zfs_prop_valid_for_type(int, zfs_type_t); +boolean_t zfs_prop_valid_for_type(int, zfs_type_t); /* * Pool property functions shared between libzfs and kernel. @@ -213,6 +226,13 @@ typedef enum zfs_share_op { ZFS_UNSHARE_SMB = 3 } zfs_share_op_t; +typedef enum zfs_cache_type { + ZFS_CACHE_NONE = 0, + ZFS_CACHE_METADATA = 1, + ZFS_CACHE_ALL = 2 +} zfs_cache_type_t; + + /* * On-disk version number. */ @@ -226,14 +246,17 @@ typedef enum zfs_share_op { #define SPA_VERSION_8 8ULL #define SPA_VERSION_9 9ULL #define SPA_VERSION_10 10ULL - +#define SPA_VERSION_11 11ULL +#define SPA_VERSION_12 12ULL +#define SPA_VERSION_13 13ULL +#define SPA_VERSION_14 14ULL /* * When bumping up SPA_VERSION, make sure GRUB ZFS understands the on-disk * format change. Go to usr/src/grub/grub-0.95/stage2/{zfs-include/, fsys_zfs*}, * and do the appropriate changes. */ -#define SPA_VERSION SPA_VERSION_10 -#define SPA_VERSION_STRING "10" +#define SPA_VERSION SPA_VERSION_14 +#define SPA_VERSION_STRING "14" /* * Symbolic names for the changes that caused a SPA_VERSION switch. @@ -263,6 +286,12 @@ typedef enum zfs_share_op { #define SPA_VERSION_REFQUOTA SPA_VERSION_9 #define SPA_VERSION_UNIQUE_ACCURATE SPA_VERSION_9 #define SPA_VERSION_L2CACHE SPA_VERSION_10 +#define SPA_VERSION_NEXT_CLONES SPA_VERSION_11 +#define SPA_VERSION_ORIGIN SPA_VERSION_11 +#define SPA_VERSION_DSL_SCRUB SPA_VERSION_11 +#define SPA_VERSION_SNAP_PROPS SPA_VERSION_12 +#define SPA_VERSION_USED_BREAKDOWN SPA_VERSION_13 +#define SPA_VERSION_PASSTHROUGH_X SPA_VERSION_14 /* * ZPL version - rev'd whenever an incompatible on-disk format change @@ -320,6 +349,7 @@ typedef enum zfs_share_op { #define ZPOOL_CONFIG_PHYS_PATH "phys_path" #define ZPOOL_CONFIG_IS_LOG "is_log" #define ZPOOL_CONFIG_L2CACHE "l2cache" +#define ZPOOL_CONFIG_SUSPENDED "suspended" /* not stored on disk */ #define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */ #define ZPOOL_CONFIG_BOOTFS "bootfs" /* not stored on disk */ /* @@ -352,11 +382,7 @@ typedef enum zfs_share_op { * The location of the pool configuration repository, shared between kernel and * userland. */ -#define ZPOOL_CACHE_DIR "/etc/zfs" -#define ZPOOL_CACHE_FILE "zpool.cache" -#define ZPOOL_CACHE_TMP ".zpool.cache" - -#define ZPOOL_CACHE ZPOOL_CACHE_DIR "/" ZPOOL_CACHE_FILE +#define ZPOOL_CACHE "/etc/zfs/zpool.cache" /* * vdev states are ordered from least to most healthy. @@ -390,7 +416,9 @@ typedef enum vdev_aux { VDEV_AUX_VERSION_NEWER, /* on-disk version is too new */ VDEV_AUX_VERSION_OLDER, /* on-disk version is too old */ VDEV_AUX_SPARED, /* hot spare used in another pool */ - VDEV_AUX_ERR_EXCEEDED /* too many errors */ + VDEV_AUX_ERR_EXCEEDED, /* too many errors */ + VDEV_AUX_IO_FAILURE, /* experienced I/O failure */ + VDEV_AUX_BAD_LOG /* cannot read log chain(s) */ } vdev_aux_t; /* @@ -406,7 +434,6 @@ typedef enum pool_state { POOL_STATE_SPARE, /* Reserved for hot spare use */ POOL_STATE_L2CACHE, /* Level 2 ARC device */ POOL_STATE_UNINITIALIZED, /* Internal spa_t state */ - POOL_STATE_IO_FAILURE, /* Internal pool state */ POOL_STATE_UNAVAIL, /* Internal libzfs state */ POOL_STATE_POTENTIALLY_ACTIVE /* Internal libzfs state */ } pool_state_t; @@ -602,6 +629,11 @@ typedef enum { #define ZFS_EV_VDEV_PATH "vdev_path" #define ZFS_EV_VDEV_GUID "vdev_guid" +/* + * Note: This is encoded on-disk, so new events must be added to the + * end, and unused events can not be removed. Be sure to edit + * zpool_main.c: hist_event_table[]. + */ typedef enum history_internal_events { LOG_NO_EVENT = 0, LOG_POOL_CREATE, @@ -640,6 +672,7 @@ typedef enum history_internal_events { LOG_DS_UPGRADE, LOG_DS_REFQUOTA, LOG_DS_REFRESERV, + LOG_POOL_SCRUB_DONE, LOG_END } history_internal_events_t; diff --git a/zfs/lib/libzcommon/include/sys/zfs_context_user.h b/zfs/lib/libzcommon/include/sys/zfs_context_user.h deleted file mode 100644 index 5ae0fdad1..000000000 --- a/zfs/lib/libzcommon/include/sys/zfs_context_user.h +++ /dev/null @@ -1,538 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ZFS_CONTEXT_H -#define _SYS_ZFS_CONTEXT_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -#define _SYS_MUTEX_H -#define _SYS_RWLOCK_H -#define _SYS_CONDVAR_H -#define _SYS_SYSTM_H -#define _SYS_DEBUG_H -#define _SYS_T_LOCK_H -#define _SYS_VNODE_H -#define _SYS_VFS_H -#define _SYS_SUNDDI_H -#define _SYS_CALLB_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Debugging - */ - -/* - * Note that we are not using the debugging levels. - */ - -#define CE_CONT 0 /* continuation */ -#define CE_NOTE 1 /* notice */ -#define CE_WARN 2 /* warning */ -#define CE_PANIC 3 /* panic */ -#define CE_IGNORE 4 /* print nothing */ - -/* - * ZFS debugging - */ - -#ifdef ZFS_DEBUG -extern void dprintf_setup(int *argc, char **argv); -#endif /* ZFS_DEBUG */ - -extern void cmn_err(int, const char *, ...); -extern void vcmn_err(int, const char *, __va_list); -extern void panic(const char *, ...); -extern void vpanic(const char *, __va_list); - -#define fm_panic panic - -/* This definition is copied from assert.h. */ -#if defined(__STDC__) -#if __STDC_VERSION__ - 0 >= 199901L -#define verify(EX) (void)((EX) || \ - (__assert_c99(#EX, __FILE__, __LINE__, __func__), 0)) -#else -#define verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0)) -#endif /* __STDC_VERSION__ - 0 >= 199901L */ -#else -#define verify(EX) (void)((EX) || (_assert("EX", __FILE__, __LINE__), 0)) -#endif /* __STDC__ */ - - -#define VERIFY verify -#define ASSERT assert - -extern void __assert(const char *, const char *, int); - -#ifdef lint -#define VERIFY3_IMPL(x, y, z, t) if (x == z) ((void)0) -#else -/* BEGIN CSTYLED */ -#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE) do { \ - const TYPE __left = (TYPE)(LEFT); \ - const TYPE __right = (TYPE)(RIGHT); \ - if (!(__left OP __right)) { \ - char *__buf = alloca(256); \ - (void) snprintf(__buf, 256, "%s %s %s (0x%llx %s 0x%llx)", \ - #LEFT, #OP, #RIGHT, \ - (u_longlong_t)__left, #OP, (u_longlong_t)__right); \ - __assert(__buf, __FILE__, __LINE__); \ - } \ -_NOTE(CONSTCOND) } while (0) -/* END CSTYLED */ -#endif /* lint */ - -#define VERIFY3S(x, y, z) VERIFY3_IMPL(x, y, z, int64_t) -#define VERIFY3U(x, y, z) VERIFY3_IMPL(x, y, z, uint64_t) -#define VERIFY3P(x, y, z) VERIFY3_IMPL(x, y, z, uintptr_t) - -#ifdef NDEBUG -#define ASSERT3S(x, y, z) ((void)0) -#define ASSERT3U(x, y, z) ((void)0) -#define ASSERT3P(x, y, z) ((void)0) -#else -#define ASSERT3S(x, y, z) VERIFY3S(x, y, z) -#define ASSERT3U(x, y, z) VERIFY3U(x, y, z) -#define ASSERT3P(x, y, z) VERIFY3P(x, y, z) -#endif - -/* - * DTrace SDT probes have different signatures in userland than they do in - * kernel. If they're being used in kernel code, re-define them out of - * existence for their counterparts in libzpool. - */ - -#ifdef DTRACE_PROBE1 -#undef DTRACE_PROBE1 -#define DTRACE_PROBE1(a, b, c) ((void)0) -#endif /* DTRACE_PROBE1 */ - -#ifdef DTRACE_PROBE2 -#undef DTRACE_PROBE2 -#define DTRACE_PROBE2(a, b, c, d, e) ((void)0) -#endif /* DTRACE_PROBE2 */ - -#ifdef DTRACE_PROBE3 -#undef DTRACE_PROBE3 -#define DTRACE_PROBE3(a, b, c, d, e, f, g) ((void)0) -#endif /* DTRACE_PROBE3 */ - -#ifdef DTRACE_PROBE4 -#undef DTRACE_PROBE4 -#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) ((void)0) -#endif /* DTRACE_PROBE4 */ - -/* - * Threads - */ -#define curthread ((void *)(uintptr_t)thr_self()) - -typedef struct kthread kthread_t; - -#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \ - zk_thread_create(func, arg) -#define thread_exit() thr_exit(NULL) - -extern kthread_t *zk_thread_create(void (*func)(), void *arg); - -#define issig(why) (FALSE) -#define ISSIG(thr, why) (FALSE) - -/* - * Mutexes - */ -typedef struct kmutex { - void *m_owner; - boolean_t initialized; - mutex_t m_lock; -} kmutex_t; - -#define MUTEX_DEFAULT USYNC_THREAD -#undef MUTEX_HELD -#define MUTEX_HELD(m) _mutex_held(&(m)->m_lock) - -/* - * Argh -- we have to get cheesy here because the kernel and userland - * have different signatures for the same routine. - */ -extern int _mutex_init(mutex_t *mp, int type, void *arg); -extern int _mutex_destroy(mutex_t *mp); - -#define mutex_init(mp, b, c, d) zmutex_init((kmutex_t *)(mp)) -#define mutex_destroy(mp) zmutex_destroy((kmutex_t *)(mp)) - -extern void zmutex_init(kmutex_t *mp); -extern void zmutex_destroy(kmutex_t *mp); -extern void mutex_enter(kmutex_t *mp); -extern void mutex_exit(kmutex_t *mp); -extern int mutex_tryenter(kmutex_t *mp); -extern void *mutex_owner(kmutex_t *mp); - -/* - * RW locks - */ -typedef struct krwlock { - void *rw_owner; - boolean_t initialized; - rwlock_t rw_lock; -} krwlock_t; - -typedef int krw_t; - -#define RW_READER 0 -#define RW_WRITER 1 -#define RW_DEFAULT USYNC_THREAD - -#undef RW_READ_HELD -#define RW_READ_HELD(x) _rw_read_held(&(x)->rw_lock) - -#undef RW_WRITE_HELD -#define RW_WRITE_HELD(x) _rw_write_held(&(x)->rw_lock) - -extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg); -extern void rw_destroy(krwlock_t *rwlp); -extern void rw_enter(krwlock_t *rwlp, krw_t rw); -extern int rw_tryenter(krwlock_t *rwlp, krw_t rw); -extern int rw_tryupgrade(krwlock_t *rwlp); -extern void rw_exit(krwlock_t *rwlp); -#define rw_downgrade(rwlp) do { } while (0) - -extern uid_t crgetuid(cred_t *cr); -extern gid_t crgetgid(cred_t *cr); -extern int crgetngroups(cred_t *cr); -extern gid_t *crgetgroups(cred_t *cr); - -/* - * Condition variables - */ -typedef cond_t kcondvar_t; - -#define CV_DEFAULT USYNC_THREAD - -extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg); -extern void cv_destroy(kcondvar_t *cv); -extern void cv_wait(kcondvar_t *cv, kmutex_t *mp); -extern clock_t cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime); -extern void cv_signal(kcondvar_t *cv); -extern void cv_broadcast(kcondvar_t *cv); - -/* - * kstat creation, installation and deletion - */ -extern kstat_t *kstat_create(char *, int, - char *, char *, uchar_t, ulong_t, uchar_t); -extern void kstat_install(kstat_t *); -extern void kstat_delete(kstat_t *); - -/* - * Kernel memory - */ -#define KM_SLEEP UMEM_NOFAIL -#define KM_NOSLEEP UMEM_DEFAULT -#define KMC_NODEBUG UMC_NODEBUG -#define kmem_alloc(_s, _f) umem_alloc(_s, _f) -#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f) -#define kmem_free(_b, _s) umem_free(_b, _s) -#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \ - umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) -#define kmem_cache_destroy(_c) umem_cache_destroy(_c) -#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f) -#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b) -#define kmem_debugging() 0 -#define kmem_cache_reap_now(c) - -typedef umem_cache_t kmem_cache_t; - -/* - * Task queues - */ -typedef struct taskq taskq_t; -typedef uintptr_t taskqid_t; -typedef void (task_func_t)(void *); - -#define TASKQ_PREPOPULATE 0x0001 -#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */ -#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */ - -#define TQ_SLEEP KM_SLEEP /* Can block for memory */ -#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */ -#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */ - -extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); -extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); -extern void taskq_destroy(taskq_t *); -extern void taskq_wait(taskq_t *); -extern int taskq_member(taskq_t *, void *); - -#define XVA_MAPSIZE 3 -#define XVA_MAGIC 0x78766174 - -/* - * vnodes - */ -typedef struct vnode { - uint64_t v_size; - int v_fd; - char *v_path; -} vnode_t; - - -typedef struct xoptattr { - timestruc_t xoa_createtime; /* Create time of file */ - uint8_t xoa_archive; - uint8_t xoa_system; - uint8_t xoa_readonly; - uint8_t xoa_hidden; - uint8_t xoa_nounlink; - uint8_t xoa_immutable; - uint8_t xoa_appendonly; - uint8_t xoa_nodump; - uint8_t xoa_settable; - uint8_t xoa_opaque; - uint8_t xoa_av_quarantined; - uint8_t xoa_av_modified; -} xoptattr_t; - -typedef struct vattr { - uint_t va_mask; /* bit-mask of attributes */ - u_offset_t va_size; /* file size in bytes */ -} vattr_t; - - -typedef struct xvattr { - vattr_t xva_vattr; /* Embedded vattr structure */ - uint32_t xva_magic; /* Magic Number */ - uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */ - uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */ - uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */ - uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */ - xoptattr_t xva_xoptattrs; /* Optional attributes */ -} xvattr_t; - -typedef struct vsecattr { - uint_t vsa_mask; /* See below */ - int vsa_aclcnt; /* ACL entry count */ - void *vsa_aclentp; /* pointer to ACL entries */ - int vsa_dfaclcnt; /* default ACL entry count */ - void *vsa_dfaclentp; /* pointer to default ACL entries */ - size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */ -} vsecattr_t; - -#define AT_TYPE 0x00001 -#define AT_MODE 0x00002 -#define AT_UID 0x00004 -#define AT_GID 0x00008 -#define AT_FSID 0x00010 -#define AT_NODEID 0x00020 -#define AT_NLINK 0x00040 -#define AT_SIZE 0x00080 -#define AT_ATIME 0x00100 -#define AT_MTIME 0x00200 -#define AT_CTIME 0x00400 -#define AT_RDEV 0x00800 -#define AT_BLKSIZE 0x01000 -#define AT_NBLOCKS 0x02000 -#define AT_SEQ 0x08000 -#define AT_XVATTR 0x10000 - -#define CRCREAT 0 - -#define VOP_CLOSE(vp, f, c, o, cr, ct) 0 -#define VOP_PUTPAGE(vp, of, sz, fl, cr, ct) 0 -#define VOP_GETATTR(vp, vap, fl, cr, ct) ((vap)->va_size = (vp)->v_size, 0) - -#define VOP_FSYNC(vp, f, cr, ct) fsync((vp)->v_fd) - -#define VN_RELE(vp) vn_close(vp) - -extern int vn_open(char *path, int x1, int oflags, int mode, vnode_t **vpp, - int x2, int x3); -extern int vn_openat(char *path, int x1, int oflags, int mode, vnode_t **vpp, - int x2, int x3, vnode_t *vp, int fd); -extern int vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, - offset_t offset, int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp); -extern void vn_close(vnode_t *vp); - -#define vn_remove(path, x1, x2) remove(path) -#define vn_rename(from, to, seg) rename((from), (to)) -#define vn_is_readonly(vp) B_FALSE - -extern vnode_t *rootdir; - -#include /* for FREAD, FWRITE, etc */ - -/* - * Random stuff - */ -#define lbolt (gethrtime() >> 23) -#define lbolt64 (gethrtime() >> 23) -#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */ - -extern void delay(clock_t ticks); - -#define gethrestime_sec() time(NULL) - -#define max_ncpus 64 - -#define minclsyspri 60 -#define maxclsyspri 99 - -#define CPU_SEQID (thr_self() & (max_ncpus - 1)) - -#define kcred NULL -#define CRED() NULL - -extern uint64_t physmem; - -extern int highbit(ulong_t i); -extern int random_get_bytes(uint8_t *ptr, size_t len); -extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len); - -extern void kernel_init(int); -extern void kernel_fini(void); - -struct spa; -extern void nicenum(uint64_t num, char *buf); -extern void show_pool_stats(struct spa *); - -typedef struct callb_cpr { - kmutex_t *cc_lockp; -} callb_cpr_t; - -#define CALLB_CPR_INIT(cp, lockp, func, name) { \ - (cp)->cc_lockp = lockp; \ -} - -#define CALLB_CPR_SAFE_BEGIN(cp) { \ - ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ -} - -#define CALLB_CPR_SAFE_END(cp, lockp) { \ - ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ -} - -#define CALLB_CPR_EXIT(cp) { \ - ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ - mutex_exit((cp)->cc_lockp); \ -} - -#define zone_dataset_visible(x, y) (1) -#define INGLOBALZONE(z) (1) - -/* - * Hostname information - */ -extern char hw_serial[]; -extern int ddi_strtoul(const char *str, char **nptr, int base, - unsigned long *result); - -/* ZFS Boot Related stuff. */ - -struct _buf { - intptr_t _fd; -}; - -struct bootstat { - uint64_t st_size; -}; - -typedef struct ace_object { - uid_t a_who; - uint32_t a_access_mask; - uint16_t a_flags; - uint16_t a_type; - uint8_t a_obj_type[16]; - uint8_t a_inherit_obj_type[16]; -} ace_object_t; - - -#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05 -#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06 -#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07 -#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08 - -extern struct _buf *kobj_open_file(char *name); -extern int kobj_read_file(struct _buf *file, char *buf, unsigned size, - unsigned off); -extern void kobj_close_file(struct _buf *file); -extern int kobj_get_filesize(struct _buf *file, uint64_t *size); -extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr); -extern int zfs_secpolicy_rename_perms(const char *from, const char *to, - cred_t *cr); -extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr); -extern zoneid_t getzoneid(void); - -/* SID stuff */ -typedef struct ksiddomain { - uint_t kd_ref; - uint_t kd_len; - char *kd_name; -} ksiddomain_t; - -ksiddomain_t *ksid_lookupdomain(const char *); -void ksiddomain_rele(ksiddomain_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_ZFS_CONTEXT_H */ diff --git a/zfs/lib/libzcommon/include/sys/zfs_i18n.h b/zfs/lib/libzcommon/include/sys/zfs_i18n.h deleted file mode 100644 index 228bfca48..000000000 --- a/zfs/lib/libzcommon/include/sys/zfs_i18n.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ZFS_I18N_H -#define _SYS_ZFS_I18N_H - - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * z_case behaviors - * The first two describe the extent of case insensitivity. - * The third describes matching behavior when mixed sensitivity - * is allowed. - */ -#define ZFS_CI_ONLY 0x01 /* all lookups case-insensitive */ -#define ZFS_CI_MIXD 0x02 /* some lookups case-insensitive */ - -/* - * ZFS_UTF8_ONLY - * If set, the file system should reject non-utf8 characters in names. - */ -#define ZFS_UTF8_ONLY 0x04 - -enum zfs_case { - ZFS_CASE_SENSITIVE, - ZFS_CASE_INSENSITIVE, - ZFS_CASE_MIXED -}; - -enum zfs_normal { - ZFS_NORMALIZE_NONE, - ZFS_NORMALIZE_D, - ZFS_NORMALIZE_KC, - ZFS_NORMALIZE_C, - ZFS_NORMALIZE_KD -}; - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_ZFS_I18N_H */ diff --git a/zfs/lib/libzcommon/include/zfs_comutil.h b/zfs/lib/libzcommon/include/zfs_comutil.h index fdef1c211..f517044a8 100644 --- a/zfs/lib/libzcommon/include/zfs_comutil.h +++ b/zfs/lib/libzcommon/include/zfs_comutil.h @@ -26,7 +26,7 @@ #ifndef _ZFS_COMUTIL_H #define _ZFS_COMUTIL_H -#pragma ident "@(#)zfs_comutil.h 1.1 08/01/25 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/zfs_deleg.h b/zfs/lib/libzcommon/include/zfs_deleg.h index 957f44861..561b73e63 100644 --- a/zfs/lib/libzcommon/include/zfs_deleg.h +++ b/zfs/lib/libzcommon/include/zfs_deleg.h @@ -26,7 +26,7 @@ #ifndef _ZFS_DELEG_H #define _ZFS_DELEG_H -#pragma ident "@(#)zfs_deleg.h 1.3 08/02/07 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/lib/libzcommon/include/zfs_namecheck.h b/zfs/lib/libzcommon/include/zfs_namecheck.h index 3a5e79520..ec85e62f7 100644 --- a/zfs/lib/libzcommon/include/zfs_namecheck.h +++ b/zfs/lib/libzcommon/include/zfs_namecheck.h @@ -26,7 +26,7 @@ #ifndef _ZFS_NAMECHECK_H #define _ZFS_NAMECHECK_H -#pragma ident "@(#)zfs_namecheck.h 1.5 07/08/01 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { diff --git a/zfs/lib/libzcommon/include/zfs_prop.h b/zfs/lib/libzcommon/include/zfs_prop.h index e06601055..da5ae4309 100644 --- a/zfs/lib/libzcommon/include/zfs_prop.h +++ b/zfs/lib/libzcommon/include/zfs_prop.h @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _ZFS_PROP_H #define _ZFS_PROP_H -#pragma ident "@(#)zfs_prop.h 1.9 07/10/25 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -120,7 +120,7 @@ int zprop_string_to_index(int, const char *, uint64_t *, zfs_type_t); int zprop_index_to_string(int, uint64_t, const char **, zfs_type_t); const char *zprop_values(int, zfs_type_t); size_t zprop_width(int, boolean_t *, zfs_type_t); -int zprop_valid_for_type(int, zfs_type_t); +boolean_t zprop_valid_for_type(int, zfs_type_t); #ifdef __cplusplus } diff --git a/zfs/lib/libzcommon/zfs_comutil.c b/zfs/lib/libzcommon/zfs_comutil.c index 1547903dc..74517a3f6 100644 --- a/zfs/lib/libzcommon/zfs_comutil.c +++ b/zfs/lib/libzcommon/zfs_comutil.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_comutil.c 1.1 08/01/25 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * This file is intended for functions that ought to be common between user diff --git a/zfs/lib/libzcommon/zfs_deleg.c b/zfs/lib/libzcommon/zfs_deleg.c index 7e3871796..0fd5800a8 100644 --- a/zfs/lib/libzcommon/zfs_deleg.c +++ b/zfs/lib/libzcommon/zfs_deleg.c @@ -24,7 +24,7 @@ */ -#pragma ident "@(#)zfs_deleg.c 1.5 08/02/07 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #if defined(_KERNEL) #include diff --git a/zfs/lib/libzcommon/zfs_namecheck.c b/zfs/lib/libzcommon/zfs_namecheck.c index eb46e3898..a9d109be2 100644 --- a/zfs/lib/libzcommon/zfs_namecheck.c +++ b/zfs/lib/libzcommon/zfs_namecheck.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zfs_namecheck.c 1.10 07/10/26 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * Common name validation routines for ZFS. These routines are shared by the @@ -54,7 +54,7 @@ valid_char(char c) return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || - c == '-' || c == '_' || c == '.' || c == ':'); + c == '-' || c == '_' || c == '.' || c == ':' || c == ' '); } /* diff --git a/zfs/lib/libzcommon/zfs_prop.c b/zfs/lib/libzcommon/zfs_prop.c index b75e7522b..effd2dba7 100644 --- a/zfs/lib/libzcommon/zfs_prop.c +++ b/zfs/lib/libzcommon/zfs_prop.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_prop.c 1.32 08/04/08 SMI" - #include #include #include @@ -99,6 +97,7 @@ zfs_prop_init(void) { "restricted", ZFS_ACL_RESTRICTED }, { "passthrough", ZFS_ACL_PASSTHROUGH }, { "secure", ZFS_ACL_RESTRICTED }, /* bkwrd compatability */ + { "passthrough-x", ZFS_ACL_PASSTHROUGH_X }, { NULL } }; @@ -151,6 +150,13 @@ zfs_prop_init(void) { NULL } }; + static zprop_index_t cache_table[] = { + { "none", ZFS_CACHE_NONE }, + { "metadata", ZFS_CACHE_METADATA }, + { "all", ZFS_CACHE_ALL }, + { NULL } + }; + /* inherit index properties */ register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, @@ -168,11 +174,19 @@ zfs_prop_init(void) "discard | groupmask | passthrough", "ACLMODE", acl_mode_table); register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, - "discard | noallow | restricted | passthrough", + "discard | noallow | restricted | passthrough | passthrough-x", "ACLINHERIT", acl_inherit_table); register_index(ZFS_PROP_COPIES, "copies", 1, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "1 | 2 | 3", "COPIES", copies_table); + register_index(ZFS_PROP_PRIMARYCACHE, "primarycache", + ZFS_CACHE_ALL, PROP_INHERIT, + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, + "all | none | metadata", "PRIMARYCACHE", cache_table); + register_index(ZFS_PROP_SECONDARYCACHE, "secondarycache", + ZFS_CACHE_ALL, PROP_INHERIT, + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, + "all | none | metadata", "SECONDARYCACHE", cache_table); /* inherit index (boolean) properties */ register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT, @@ -254,6 +268,15 @@ zfs_prop_init(void) register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192, PROP_ONETIME, ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK"); + register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0, PROP_READONLY, + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "", "USEDSNAP"); + register_number(ZFS_PROP_USEDDS, "usedbydataset", 0, PROP_READONLY, + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "", "USEDDS"); + register_number(ZFS_PROP_USEDCHILD, "usedbychildren", 0, PROP_READONLY, + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "", "USEDCHILD"); + register_number(ZFS_PROP_USEDREFRESERV, "usedbyrefreservation", 0, + PROP_READONLY, + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "", "USEDREFRESERV"); /* default number properties */ register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT, @@ -282,6 +305,8 @@ zfs_prop_init(void) PROP_READONLY, ZFS_TYPE_DATASET, "NAME"); register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS"); + register_hidden(ZFS_PROP_GUID, "guid", PROP_TYPE_NUMBER, PROP_READONLY, + ZFS_TYPE_DATASET, "GUID"); /* oddball properties */ register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL, @@ -361,7 +386,7 @@ zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string) /* * Returns TRUE if the property applies to any of the given dataset types. */ -int +boolean_t zfs_prop_valid_for_type(int prop, zfs_type_t types) { return (zprop_valid_for_type(prop, types)); diff --git a/zfs/lib/libzcommon/zpool_prop.c b/zfs/lib/libzcommon/zpool_prop.c index b8ffd8ffc..f5efe18d2 100644 --- a/zfs/lib/libzcommon/zpool_prop.c +++ b/zfs/lib/libzcommon/zpool_prop.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zpool_prop.c 1.4 07/11/20 SMI" - #include #include #include @@ -96,6 +94,8 @@ zpool_prop_init(void) ZFS_TYPE_POOL, "on | off", "DELEGATION", boolean_table); register_index(ZPOOL_PROP_AUTOREPLACE, "autoreplace", 0, PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "REPLACE", boolean_table); + register_index(ZPOOL_PROP_LISTSNAPS, "listsnapshots", 0, PROP_DEFAULT, + ZFS_TYPE_POOL, "on | off", "LISTSNAPS", boolean_table); /* default index properties */ register_index(ZPOOL_PROP_FAILUREMODE, "failmode", diff --git a/zfs/lib/libzcommon/zprop_common.c b/zfs/lib/libzcommon/zprop_common.c index add8b8353..bd267e2e6 100644 --- a/zfs/lib/libzcommon/zprop_common.c +++ b/zfs/lib/libzcommon/zprop_common.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zprop_common.c 1.1 07/09/17 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * Common routines used by zfs and zpool property management. @@ -268,6 +268,10 @@ zprop_string_to_index(int prop, const char *string, uint64_t *index, const zprop_index_t *idx_tbl; int i; + if (prop == ZPROP_INVAL || prop == ZPROP_CONT) + return (-1); + + ASSERT(prop < zprop_get_numprops(type)); prop_tbl = zprop_get_proptable(type); if ((idx_tbl = prop_tbl[prop].pd_table) == NULL) return (-1); @@ -290,6 +294,10 @@ zprop_index_to_string(int prop, uint64_t index, const char **string, const zprop_index_t *idx_tbl; int i; + if (prop == ZPROP_INVAL || prop == ZPROP_CONT) + return (-1); + + ASSERT(prop < zprop_get_numprops(type)); prop_tbl = zprop_get_proptable(type); if ((idx_tbl = prop_tbl[prop].pd_table) == NULL) return (-1); @@ -309,6 +317,9 @@ zprop_values(int prop, zfs_type_t type) { zprop_desc_t *prop_tbl; + ASSERT(prop != ZPROP_INVAL && prop != ZPROP_CONT); + ASSERT(prop < zprop_get_numprops(type)); + prop_tbl = zprop_get_proptable(type); return (prop_tbl[prop].pd_values); @@ -317,11 +328,16 @@ zprop_values(int prop, zfs_type_t type) /* * Returns TRUE if the property applies to any of the given dataset types. */ -int +boolean_t zprop_valid_for_type(int prop, zfs_type_t type) { - zprop_desc_t *prop_tbl = zprop_get_proptable(type); + zprop_desc_t *prop_tbl; + if (prop == ZPROP_INVAL || prop == ZPROP_CONT) + return (B_FALSE); + + ASSERT(prop < zprop_get_numprops(type)); + prop_tbl = zprop_get_proptable(type); return ((prop_tbl[prop].pd_types & type) != 0); } @@ -339,6 +355,9 @@ zprop_width(int prop, boolean_t *fixed, zfs_type_t type) size_t ret; int i; + ASSERT(prop != ZPROP_INVAL && prop != ZPROP_CONT); + ASSERT(prop < zprop_get_numprops(type)); + prop_tbl = zprop_get_proptable(type); pd = &prop_tbl[prop]; diff --git a/zfs/lib/libzfs/include/libzfs.h b/zfs/lib/libzfs/include/libzfs.h index 9d5fed578..c650865f3 100644 --- a/zfs/lib/libzfs/include/libzfs.h +++ b/zfs/lib/libzfs/include/libzfs.h @@ -27,8 +27,6 @@ #ifndef _LIBZFS_H #define _LIBZFS_H -#pragma ident "@(#)libzfs.h 1.51 08/04/01 SMI" - #include #include #include @@ -115,6 +113,8 @@ enum { EZFS_BADCACHE, /* bad cache file */ EZFS_ISL2CACHE, /* device is for the level 2 ARC */ EZFS_VDEVNOTSUP, /* unsupported vdev type */ + EZFS_NOTSUP, /* ops not supported on this dataset */ + EZFS_ACTIVE_SPARE, /* pool has active shared spare devices */ EZFS_UNKNOWN }; @@ -185,6 +185,7 @@ extern void zpool_close(zpool_handle_t *); extern const char *zpool_get_name(zpool_handle_t *); extern int zpool_get_state(zpool_handle_t *); extern char *zpool_state_to_name(vdev_state_t, vdev_aux_t); +extern void zpool_free_handles(libzfs_handle_t *); /* * Iterate over all active pools in the system. @@ -196,7 +197,7 @@ extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *); * Functions to create and destroy pools */ extern int zpool_create(libzfs_handle_t *, const char *, nvlist_t *, - nvlist_t *); + nvlist_t *, nvlist_t *); extern int zpool_destroy(zpool_handle_t *); extern int zpool_add(zpool_handle_t *, nvlist_t *); @@ -219,7 +220,7 @@ extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t); extern int zpool_vdev_clear(zpool_handle_t *, uint64_t); extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *, - boolean_t *); + boolean_t *, boolean_t *); extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, char *); /* @@ -253,8 +254,11 @@ typedef enum { ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */ ZPOOL_STATUS_VERSION_NEWER, /* newer on-disk version */ ZPOOL_STATUS_HOSTID_MISMATCH, /* last accessed by another system */ + ZPOOL_STATUS_IO_FAILURE_WAIT, /* failed I/O, failmode 'wait' */ + ZPOOL_STATUS_IO_FAILURE_CONTINUE, /* failed I/O, failmode 'continue' */ ZPOOL_STATUS_FAULTED_DEV_R, /* faulted device with replicas */ ZPOOL_STATUS_FAULTED_DEV_NR, /* faulted device with no replicas */ + ZPOOL_STATUS_BAD_LOG, /* cannot read log chain(s) */ /* * The following are not faults per se, but still an error possibly @@ -284,18 +288,23 @@ extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **); /* * Import and export functions */ -extern int zpool_export(zpool_handle_t *); +extern int zpool_export(zpool_handle_t *, boolean_t); extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *, char *altroot); extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *, - nvlist_t *); + nvlist_t *, boolean_t); /* * Search for pools to import */ -extern nvlist_t *zpool_find_import(libzfs_handle_t *, int, char **, boolean_t); +extern nvlist_t *zpool_find_import(libzfs_handle_t *, int, char **); extern nvlist_t *zpool_find_import_cached(libzfs_handle_t *, const char *, -boolean_t); + char *, uint64_t); +extern nvlist_t *zpool_find_import_byname(libzfs_handle_t *, int, char **, + char *); +extern nvlist_t *zpool_find_import_byguid(libzfs_handle_t *, int, char **, + uint64_t); +extern nvlist_t *zpool_find_import_activeok(libzfs_handle_t *, int, char **); /* * Miscellaneous pool functions @@ -311,6 +320,7 @@ extern int zpool_stage_history(libzfs_handle_t *, const char *); extern void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *, size_t len); extern int zfs_ioctl(libzfs_handle_t *, int, struct zfs_cmd *); +extern int zpool_get_physpath(zpool_handle_t *, char *); /* * Basic handle manipulations. These functions do not create or destroy the * underlying datasets, only the references to them. @@ -319,6 +329,7 @@ extern zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int); extern void zfs_close(zfs_handle_t *); extern zfs_type_t zfs_get_type(const zfs_handle_t *); extern const char *zfs_get_name(const zfs_handle_t *); +extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *); /* * Property management functions. Some functions are shared with the kernel, @@ -333,6 +344,9 @@ extern uint64_t zfs_prop_default_numeric(zfs_prop_t); extern const char *zfs_prop_column_name(zfs_prop_t); extern boolean_t zfs_prop_align_right(zfs_prop_t); +extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t, + nvlist_t *, uint64_t, zfs_handle_t *, const char *); + extern const char *zfs_prop_to_name(zfs_prop_t); extern int zfs_prop_set(zfs_handle_t *, const char *, const char *); extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t, @@ -418,7 +432,7 @@ extern int zfs_create_ancestors(libzfs_handle_t *, const char *); extern int zfs_destroy(zfs_handle_t *); extern int zfs_destroy_snaps(zfs_handle_t *, char *); extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *); -extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t); +extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *); extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t); extern int zfs_rename(zfs_handle_t *, const char *, boolean_t); extern int zfs_send(zfs_handle_t *, const char *, const char *, diff --git a/zfs/lib/libzfs/include/libzfs_impl.h b/zfs/lib/libzfs/include/libzfs_impl.h index 88bbd94d6..9f1f66d51 100644 --- a/zfs/lib/libzfs/include/libzfs_impl.h +++ b/zfs/lib/libzfs/include/libzfs_impl.h @@ -27,8 +27,6 @@ #ifndef _LIBFS_IMPL_H #define _LIBFS_IMPL_H -#pragma ident "@(#)libzfs_impl.h 1.27 08/04/14 SMI" - #include #include #include @@ -54,6 +52,7 @@ struct libzfs_handle { int libzfs_fd; FILE *libzfs_mnttab; FILE *libzfs_sharetab; + zpool_handle_t *libzfs_pool_handles; uu_avl_pool_t *libzfs_ns_avlpool; uu_avl_t *libzfs_ns_avl; uint64_t libzfs_ns_gen; @@ -69,6 +68,7 @@ struct libzfs_handle { struct zfs_handle { libzfs_handle_t *zfs_hdl; + zpool_handle_t *zpool_hdl; char zfs_name[ZFS_MAXNAMELEN]; zfs_type_t zfs_type; /* type including snapshot */ zfs_type_t zfs_head_type; /* type excluding snapshot */ @@ -77,7 +77,6 @@ struct zfs_handle { nvlist_t *zfs_user_props; boolean_t zfs_mntcheck; char *zfs_mntopts; - char zfs_root[MAXPATHLEN]; }; /* @@ -88,6 +87,7 @@ struct zfs_handle { struct zpool_handle { libzfs_handle_t *zpool_hdl; + zpool_handle_t *zpool_next; char zpool_name[ZPOOL_MAXNAMELEN]; int zpool_state; size_t zpool_config_size; @@ -136,6 +136,13 @@ int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t, int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type); +/* + * Use this changelist_gather() flag to force attempting mounts + * on each change node regardless of whether or not it is currently + * mounted. + */ +#define CL_GATHER_MOUNT_ALWAYS 1 + typedef struct prop_changelist prop_changelist_t; int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t); @@ -150,7 +157,7 @@ int changelist_postfix(prop_changelist_t *); void changelist_rename(prop_changelist_t *, const char *, const char *); void changelist_remove(prop_changelist_t *, const char *); void changelist_free(prop_changelist_t *); -prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int); +prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, int); int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *); int changelist_haszonedchild(prop_changelist_t *); diff --git a/zfs/lib/libzfs/libzfs_changelist.c b/zfs/lib/libzfs/libzfs_changelist.c index a75b34df2..b905bc6cb 100644 --- a/zfs/lib/libzfs/libzfs_changelist.c +++ b/zfs/lib/libzfs/libzfs_changelist.c @@ -26,8 +26,6 @@ * Portions Copyright 2007 Ramprakash Jelari */ -#pragma ident "@(#)libzfs_changelist.c 1.23 08/03/04 SMI" - #include #include #include @@ -80,7 +78,8 @@ struct prop_changelist { boolean_t cl_waslegacy; boolean_t cl_allchildren; boolean_t cl_alldependents; - int cl_flags; + int cl_mflags; /* Mount flags */ + int cl_gflags; /* Gather request flags */ boolean_t cl_haszonedchild; boolean_t cl_sorted; }; @@ -149,7 +148,7 @@ changelist_prefix(prop_changelist_t *clp) switch (clp->cl_prop) { case ZFS_PROP_MOUNTPOINT: if (zfs_unmount(cn->cn_handle, NULL, - clp->cl_flags) != 0) { + clp->cl_mflags) != 0) { ret = -1; cn->cn_needpost = B_FALSE; } @@ -480,7 +479,8 @@ change_one(zfs_handle_t *zhp, void *data) } cn->cn_handle = zhp; - cn->cn_mounted = zfs_is_mounted(zhp, NULL); + cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) || + zfs_is_mounted(zhp, NULL); cn->cn_shared = zfs_is_shared(zhp); cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); cn->cn_needpost = B_TRUE; @@ -556,7 +556,8 @@ compare_mountpoints(const void *a, const void *b, void *unused) * mark whether it was shared beforehand. */ prop_changelist_t * -changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags) +changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags, + int mnt_flags) { prop_changelist_t *clp; prop_changenode_t *cn; @@ -592,7 +593,8 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags) clp->cl_list = uu_list_create(clp->cl_pool, NULL, clp->cl_sorted ? UU_LIST_SORTED : 0); - clp->cl_flags = flags; + clp->cl_gflags = gather_flags; + clp->cl_mflags = mnt_flags; if (clp->cl_list == NULL) { assert(uu_error() == UU_ERROR_NO_MEMORY); @@ -673,7 +675,8 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags) } cn->cn_handle = temp; - cn->cn_mounted = zfs_is_mounted(temp, NULL); + cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) || + zfs_is_mounted(temp, NULL); cn->cn_shared = zfs_is_shared(temp); cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); cn->cn_needpost = B_TRUE; diff --git a/zfs/lib/libzfs/libzfs_config.c b/zfs/lib/libzfs/libzfs_config.c index 95e413c0f..94640d1b1 100644 --- a/zfs/lib/libzfs/libzfs_config.c +++ b/zfs/lib/libzfs/libzfs_config.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_config.c 1.9 07/04/19 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * The pool configuration repository is stored in /etc/zfs/zpool.cache as a diff --git a/zfs/lib/libzfs/libzfs_dataset.c b/zfs/lib/libzfs/libzfs_dataset.c index 5b8119209..a8005ffc0 100644 --- a/zfs/lib/libzfs/libzfs_dataset.c +++ b/zfs/lib/libzfs/libzfs_dataset.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_dataset.c 1.79 08/04/01 SMI" - #include #include #include @@ -254,6 +252,69 @@ process_user_props(zfs_handle_t *zhp, nvlist_t *props) return (nvl); } +static zpool_handle_t * +zpool_add_handle(zfs_handle_t *zhp, const char *pool_name) +{ + libzfs_handle_t *hdl = zhp->zfs_hdl; + zpool_handle_t *zph; + + if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) { + if (hdl->libzfs_pool_handles != NULL) + zph->zpool_next = hdl->libzfs_pool_handles; + hdl->libzfs_pool_handles = zph; + } + return (zph); +} + +static zpool_handle_t * +zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len) +{ + libzfs_handle_t *hdl = zhp->zfs_hdl; + zpool_handle_t *zph = hdl->libzfs_pool_handles; + + while ((zph != NULL) && + (strncmp(pool_name, zpool_get_name(zph), len) != 0)) + zph = zph->zpool_next; + return (zph); +} + +/* + * Returns a handle to the pool that contains the provided dataset. + * If a handle to that pool already exists then that handle is returned. + * Otherwise, a new handle is created and added to the list of handles. + */ +static zpool_handle_t * +zpool_handle(zfs_handle_t *zhp) +{ + char *pool_name; + int len; + zpool_handle_t *zph; + + len = strcspn(zhp->zfs_name, "/@") + 1; + pool_name = zfs_alloc(zhp->zfs_hdl, len); + (void) strlcpy(pool_name, zhp->zfs_name, len); + + zph = zpool_find_handle(zhp, pool_name, len); + if (zph == NULL) + zph = zpool_add_handle(zhp, pool_name); + + free(pool_name); + return (zph); +} + +void +zpool_free_handles(libzfs_handle_t *hdl) +{ + zpool_handle_t *next, *zph = hdl->libzfs_pool_handles; + + while (zph != NULL) { + next = zph->zpool_next; + zpool_close(zph); + zph = next; + } + hdl->libzfs_pool_handles = NULL; +} + /* * Utility function to gather stats (objset and zpl) for the given object. */ @@ -283,8 +344,6 @@ get_stats(zfs_handle_t *zhp) zhp->zfs_dmustats = zc.zc_objset_stats; /* structure assignment */ - (void) strlcpy(zhp->zfs_root, zc.zc_value, sizeof (zhp->zfs_root)); - if (zcmd_read_dst_nvlist(hdl, &zc, &allprops) != 0) { zcmd_free_nvlists(&zc); return (-1); @@ -409,6 +468,7 @@ top: abort(); /* we should never see any other types */ zhp->zfs_hdl->libzfs_log_str = logstr; + zhp->zpool_hdl = zpool_handle(zhp); return (zhp); } @@ -470,27 +530,13 @@ zfs_close(zfs_handle_t *zhp) int zfs_spa_version(zfs_handle_t *zhp, int *spa_version) { - char *pool_name; - zpool_handle_t *zpool_handle; - char *p; + zpool_handle_t *zpool_handle = zhp->zpool_hdl; - pool_name = zfs_alloc(zhp->zfs_hdl, MAXPATHLEN); - if (zfs_prop_get(zhp, ZFS_PROP_NAME, pool_name, - MAXPATHLEN, NULL, NULL, 0, B_FALSE) != 0) { - free(pool_name); - return (-1); - } - - if (p = strchr(pool_name, '/')) - *p = '\0'; - zpool_handle = zpool_open(zhp->zfs_hdl, pool_name); - free(pool_name); if (zpool_handle == NULL) return (-1); *spa_version = zpool_get_prop_int(zpool_handle, ZPOOL_PROP_VERSION, NULL); - zpool_close(zpool_handle); return (0); } @@ -518,8 +564,8 @@ zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop) * parses any numeric properties (index, boolean, etc) if they are specified as * strings. */ -static nvlist_t * -zfs_validate_properties(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, +nvlist_t * +zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, uint64_t zoned, zfs_handle_t *zhp, const char *errbuf) { nvpair_t *elem; @@ -530,13 +576,6 @@ zfs_validate_properties(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, int chosen_normal = -1; int chosen_utf = -1; - if (type == ZFS_TYPE_SNAPSHOT) { - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "snapshot properties cannot be modified")); - (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf); - return (NULL); - } - if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) { (void) no_memory(hdl); return (NULL); @@ -584,6 +623,13 @@ zfs_validate_properties(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, continue; } + if (type == ZFS_TYPE_SNAPSHOT) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "this property can not be modified for snapshots")); + (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf); + goto error; + } + if (!zfs_prop_valid_for_type(prop, type)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' does not " @@ -1722,7 +1768,8 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) libzfs_handle_t *hdl = zhp->zfs_hdl; nvlist_t *nvl = NULL, *realprops; zfs_prop_t prop; - int do_prefix = 1; + boolean_t do_prefix; + uint64_t idx; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "cannot set property for '%s'"), @@ -1734,7 +1781,7 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) goto error; } - if ((realprops = zfs_validate_properties(hdl, zhp->zfs_type, nvl, + if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl, zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL) goto error; @@ -1743,7 +1790,7 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) prop = zfs_name_to_prop(propname); - if ((cl = changelist_gather(zhp, prop, 0)) == NULL) + if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL) goto error; if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) { @@ -1754,13 +1801,16 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) goto error; } - - /* do not unmount dataset if canmount is being set to noauto */ - if (prop == ZFS_PROP_CANMOUNT && *propval == ZFS_CANMOUNT_NOAUTO) - do_prefix = 0; + /* + * If the dataset's canmount property is being set to noauto, + * then we want to prevent unmounting & remounting it. + */ + do_prefix = !((prop == ZFS_PROP_CANMOUNT) && + (zprop_string_to_index(prop, propval, &idx, + ZFS_TYPE_DATASET) == 0) && (idx == ZFS_CANMOUNT_NOAUTO)); if (do_prefix && (ret = changelist_prefix(cl)) != 0) - goto error; + goto error; /* * Execute the corresponding ioctl() to set this property. @@ -1820,6 +1870,17 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval) (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); break; + case ERANGE: + if (prop == ZFS_PROP_COMPRESSION) { + (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "property setting is not allowed on " + "bootable datasets")); + (void) zfs_error(hdl, EZFS_NOTSUP, errbuf); + } else { + (void) zfs_standard_error(hdl, errno, errbuf); + } + break; + case EOVERFLOW: /* * This platform can't address a volume this big. @@ -1922,7 +1983,7 @@ zfs_prop_inherit(zfs_handle_t *zhp, const char *propname) /* * Determine datasets which will be affected by this change, if any. */ - if ((cl = changelist_gather(zhp, prop, 0)) == NULL) + if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL) return (-1); if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) { @@ -2168,6 +2229,15 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, case PROP_TYPE_NUMBER: case PROP_TYPE_INDEX: *val = getprop_uint64(zhp, prop, source); + /* + * If we tried to use a defalut value for a + * readonly property, it means that it was not + * present; return an error. + */ + if (zfs_prop_readonly(prop) && + *source && (*source)[0] == '\0') { + return (-1); + } break; case PROP_TYPE_STRING: @@ -2221,7 +2291,6 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, char *source = NULL; uint64_t val; char *str; - const char *root; const char *strval; /* @@ -2257,25 +2326,42 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, * Getting the precise mountpoint can be tricky. * * - for 'none' or 'legacy', return those values. - * - for default mountpoints, construct it as /zfs/ * - for inherited mountpoints, we want to take everything * after our ancestor and append it to the inherited value. * * If the pool has an alternate root, we want to prepend that * root to any values we return. */ - root = zhp->zfs_root; + str = getprop_string(zhp, prop, &source); - if (str[0] == '\0') { - (void) snprintf(propbuf, proplen, "%s/zfs/%s", - root, zhp->zfs_name); - } else if (str[0] == '/') { + if (str[0] == '/') { + char buf[MAXPATHLEN]; + char *root = buf; const char *relpath = zhp->zfs_name + strlen(source); if (relpath[0] == '/') relpath++; - if (str[1] == '\0') + + if ((zpool_get_prop(zhp->zpool_hdl, + ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) || + (strcmp(root, "-") == 0)) + root[0] = '\0'; + /* + * Special case an alternate root of '/'. This will + * avoid having multiple leading slashes in the + * mountpoint path. + */ + if (strcmp(root, "/") == 0) + root++; + + /* + * If the mountpoint is '/' then skip over this + * if we are obtaining either an alternate root or + * an inherited mountpoint. + */ + if (str[1] == '\0' && (root[0] != '\0' || + relpath[0] != '\0')) str++; if (relpath[0] == '\0') @@ -2859,7 +2945,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type, else zc.zc_objset_type = DMU_OST_ZFS; - if (props && (props = zfs_validate_properties(hdl, type, props, + if (props && (props = zfs_valid_proplist(hdl, type, props, zoned, NULL, errbuf)) == 0) return (-1); @@ -3142,8 +3228,8 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props) } if (props) { - if ((props = zfs_validate_properties(hdl, type, props, - zoned, zhp, errbuf)) == NULL) + if ((props = zfs_valid_proplist(hdl, type, props, zoned, + zhp, errbuf)) == NULL) return (-1); if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) { @@ -3375,10 +3461,11 @@ zfs_create_link_cb(zfs_handle_t *zhp, void *arg) * Takes a snapshot of the given dataset. */ int -zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive) +zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive, + nvlist_t *props) { const char *delim; - char *parent; + char parent[ZFS_MAXNAMELEN]; zfs_handle_t *zhp; zfs_cmd_t zc = { 0 }; int ret; @@ -3391,16 +3478,27 @@ zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive) if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE)) return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); + if (props) { + if ((props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT, + props, B_FALSE, NULL, errbuf)) == NULL) + return (-1); + + if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) { + nvlist_free(props); + return (-1); + } + + nvlist_free(props); + } + /* make sure the parent exists and is of the appropriate type */ delim = strchr(path, '@'); - if ((parent = zfs_alloc(hdl, delim - path + 1)) == NULL) - return (-1); (void) strncpy(parent, path, delim - path); parent[delim - path] = '\0'; if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) { - free(parent); + zcmd_free_nvlists(&zc); return (-1); } @@ -3413,6 +3511,8 @@ zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive) zc.zc_cookie = recursive; ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SNAPSHOT, &zc); + zcmd_free_nvlists(&zc); + /* * if it was recursive, the one that actually failed will be in * zc.zc_name. @@ -3435,7 +3535,6 @@ zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive) dgettext(TEXT_DOMAIN, "Volume successfully snapshotted, but device links " "were not created")); - free(parent); zfs_close(zhp); return (-1); } @@ -3444,7 +3543,6 @@ zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive) if (ret != 0) (void) zfs_standard_error(hdl, errno, errbuf); - free(parent); zfs_close(zhp); return (ret); @@ -3490,7 +3588,7 @@ rollback_destroy(zfs_handle_t *zhp, void *data) /* We must destroy this clone; first unmount it */ prop_changelist_t *clp; - clp = changelist_gather(zhp, ZFS_PROP_NAME, + clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, cbp->cb_force ? MS_FORCE: 0); if (clp == NULL || changelist_prefix(clp) != 0) { cbp->cb_error = B_TRUE; @@ -3766,7 +3864,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive) goto error; } } else { - if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0)) == NULL) + if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0)) == NULL) return (-1); if (changelist_haszonedchild(cl)) { @@ -3918,7 +4016,7 @@ zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists) if ((dhdl = di_devlink_init(ZFS_DRIVER, DI_MAKE_LINK)) == NULL) { zfs_error_aux(hdl, strerror(errno)); - (void) zfs_standard_error_fmt(hdl, EZFS_DEVLINKS, + (void) zfs_error_fmt(hdl, errno, dgettext(TEXT_DOMAIN, "cannot create device links " "for '%s'"), dataset); (void) ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc); diff --git a/zfs/lib/libzfs/libzfs_graph.c b/zfs/lib/libzfs/libzfs_graph.c index 0d11e84e0..e7cbf2386 100644 --- a/zfs/lib/libzfs/libzfs_graph.c +++ b/zfs/lib/libzfs/libzfs_graph.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_graph.c 1.8 08/02/27 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * Iterate over all children of the current object. This includes the normal diff --git a/zfs/lib/libzfs/libzfs_import.c b/zfs/lib/libzfs/libzfs_import.c index 4bbd07fbe..d67776889 100644 --- a/zfs/lib/libzfs/libzfs_import.c +++ b/zfs/lib/libzfs/libzfs_import.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_import.c 1.24 08/04/08 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * Pool import support functions. @@ -429,6 +429,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok) boolean_t isactive; uint64_t hostid; nvlist_t *nvl; + boolean_t found_one = B_FALSE; if (nvlist_alloc(&ret, 0, 0) != 0) goto nomem; @@ -689,10 +690,16 @@ add_pool: if (nvlist_add_nvlist(ret, name, config) != 0) goto nomem; + found_one = B_TRUE; nvlist_free(config); config = NULL; } + if (!found_one) { + nvlist_free(ret); + ret = NULL; + } + return (ret); nomem: @@ -740,7 +747,7 @@ zpool_read_label(int fd, nvlist_t **config) return (-1); for (l = 0; l < VDEV_LABELS; l++) { - if (pread(fd, label, sizeof (vdev_label_t), + if (pread64(fd, label, sizeof (vdev_label_t), label_offset(size, l)) != sizeof (vdev_label_t)) continue; @@ -774,10 +781,12 @@ zpool_read_label(int fd, nvlist_t **config) * Given a list of directories to search, find all pools stored on disk. This * includes partial pools which are not available to import. If no args are * given (argc is 0), then the default directory (/dev/dsk) is searched. + * poolname or guid (but not both) are provided by the caller when trying + * to import a specific pool. */ -nvlist_t * -zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv, - boolean_t active_ok) +static nvlist_t * +zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv, + boolean_t active_ok, char *poolname, uint64_t guid) { int i; DIR *dirp = NULL; @@ -795,6 +804,8 @@ zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv, config_entry_t *ce, *cenext; name_entry_t *ne, *nenext; + verify(poolname == NULL || guid == 0); + if (argc == 0) { argc = 1; argv = &default_dir; @@ -873,6 +884,28 @@ zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv, (void) close(fd); if (config != NULL) { + boolean_t matched = B_TRUE; + + if (poolname != NULL) { + char *pname; + + matched = nvlist_lookup_string(config, + ZPOOL_CONFIG_POOL_NAME, + &pname) == 0 && + strcmp(poolname, pname) == 0; + } else if (guid != 0) { + uint64_t this_guid; + + matched = nvlist_lookup_uint64(config, + ZPOOL_CONFIG_POOL_GUID, + &this_guid) == 0 && + guid == this_guid; + } + if (!matched) { + nvlist_free(config); + config = NULL; + continue; + } /* use the non-raw path for the config */ (void) strlcpy(end, name, pathleft); if (add_config(hdl, &pools, path, config) != 0) @@ -915,12 +948,40 @@ error: return (ret); } +nvlist_t * +zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv) +{ + return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, 0)); +} + +nvlist_t * +zpool_find_import_byname(libzfs_handle_t *hdl, int argc, char **argv, + char *pool) +{ + return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, pool, 0)); +} + +nvlist_t * +zpool_find_import_byguid(libzfs_handle_t *hdl, int argc, char **argv, + uint64_t guid) +{ + return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, guid)); +} + +nvlist_t * +zpool_find_import_activeok(libzfs_handle_t *hdl, int argc, char **argv) +{ + return (zpool_find_import_impl(hdl, argc, argv, B_TRUE, NULL, 0)); +} + /* * Given a cache file, return the contents as a list of importable pools. + * poolname or guid (but not both) are provided by the caller when trying + * to import a specific pool. */ nvlist_t * zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile, - boolean_t active_ok) + char *poolname, uint64_t guid) { char *buf; int fd; @@ -929,9 +990,11 @@ zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile, nvlist_t *pools; nvpair_t *elem; char *name; - uint64_t guid; + uint64_t this_guid; boolean_t active; + verify(poolname == NULL || guid == 0); + if ((fd = open(cachefile, O_RDONLY)) < 0) { zfs_error_aux(hdl, "%s", strerror(errno)); (void) zfs_error(hdl, EZFS_BADCACHE, @@ -989,43 +1052,41 @@ zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile, verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME, &name) == 0); + if (poolname != NULL && strcmp(poolname, name) != 0) + continue; + verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID, - &guid) == 0); - - if (!active_ok) { - if (pool_active(hdl, name, guid, &active) != 0) { - nvlist_free(raw); - nvlist_free(pools); - return (NULL); - } - - if (active) + &this_guid) == 0); + if (guid != 0) { + verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID, + &this_guid) == 0); + if (guid != this_guid) continue; - - if ((dst = refresh_config(hdl, src)) == NULL) { - nvlist_free(raw); - nvlist_free(pools); - return (NULL); - } - - if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) - != 0) { - (void) no_memory(hdl); - nvlist_free(dst); - nvlist_free(raw); - nvlist_free(pools); - return (NULL); - } - nvlist_free(dst); - } else { - if (nvlist_add_nvlist(pools, nvpair_name(elem), src) - != 0) { - (void) no_memory(hdl); - nvlist_free(raw); - nvlist_free(pools); - return (NULL); - } } + + if (pool_active(hdl, name, this_guid, &active) != 0) { + nvlist_free(raw); + nvlist_free(pools); + return (NULL); + } + + if (active) + continue; + + if ((dst = refresh_config(hdl, src)) == NULL) { + nvlist_free(raw); + nvlist_free(pools); + return (NULL); + } + + if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) { + (void) no_memory(hdl); + nvlist_free(dst); + nvlist_free(raw); + nvlist_free(pools); + return (NULL); + } + nvlist_free(dst); } nvlist_free(raw); diff --git a/zfs/lib/libzfs/libzfs_mount.c b/zfs/lib/libzfs/libzfs_mount.c index 35a2cea7a..7c5c7f3ec 100644 --- a/zfs/lib/libzfs/libzfs_mount.c +++ b/zfs/lib/libzfs/libzfs_mount.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_mount.c 1.25 08/03/04 SMI" - /* * Routines to manage ZFS mounts. We separate all the nasty routines that have * to deal with the OS. The following functions are the main entry points -- @@ -440,7 +438,7 @@ zfs_unmountall(zfs_handle_t *zhp, int flags) prop_changelist_t *clp; int ret; - clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, flags); + clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, 0, flags); if (clp == NULL) return (-1); @@ -945,7 +943,7 @@ zfs_unshareall_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) prop_changelist_t *clp; int ret; - clp = changelist_gather(zhp, ZFS_PROP_SHARENFS, 0); + clp = changelist_gather(zhp, ZFS_PROP_SHARENFS, 0, 0); if (clp == NULL) return (-1); diff --git a/zfs/lib/libzfs/libzfs_pool.c b/zfs/lib/libzfs/libzfs_pool.c index bac9f8685..dc5407bef 100644 --- a/zfs/lib/libzfs/libzfs_pool.c +++ b/zfs/lib/libzfs/libzfs_pool.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_pool.c 1.44 08/04/11 SMI" - #include #include #include @@ -38,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +47,13 @@ #include "zfs_prop.h" #include "libzfs_impl.h" +static int read_efi_label(nvlist_t *config, diskaddr_t *sb); + +#if defined(__i386) || defined(__amd64) +#define BOOTCMD "installgrub(1M)" +#else +#define BOOTCMD "installboot(1M)" +#endif /* * ==================================================================== @@ -135,8 +141,21 @@ zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src) uint64_t value; zprop_source_t source; - if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) + if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) { + /* + * zpool_get_all_props() has most likely failed because + * the pool is faulted, but if all we need is the top level + * vdev's guid then get it from the zhp config nvlist. + */ + if ((prop == ZPOOL_PROP_GUID) && + (nvlist_lookup_nvlist(zhp->zpool_config, + ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) && + (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value) + == 0)) { + return (value); + } return (zpool_prop_default_numeric(prop)); + } nvl = zhp->zpool_props; if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) { @@ -167,7 +186,7 @@ zpool_state_to_name(vdev_state_t state, vdev_aux_t aux) case VDEV_STATE_REMOVED: return (gettext("REMOVED")); case VDEV_STATE_CANT_OPEN: - if (aux == VDEV_AUX_CORRUPT_DATA) + if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG) return (gettext("FAULTED")); else return (gettext("UNAVAIL")); @@ -273,7 +292,7 @@ bootfs_name_valid(const char *pool, char *bootfs) { int len = strlen(pool); - if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM)) + if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT)) return (B_FALSE); if (strncmp(pool, bootfs, len) == 0 && @@ -283,13 +302,45 @@ bootfs_name_valid(const char *pool, char *bootfs) return (B_FALSE); } +/* + * Inspect the configuration to determine if any of the devices contain + * an EFI label. + */ +static boolean_t +pool_uses_efi(nvlist_t *config) +{ + nvlist_t **child; + uint_t c, children; + + if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN, + &child, &children) != 0) + return (read_efi_label(config, NULL) >= 0); + + for (c = 0; c < children; c++) { + if (pool_uses_efi(child[c])) + return (B_TRUE); + } + return (B_FALSE); +} + +static boolean_t +pool_is_bootable(zpool_handle_t *zhp) +{ + char bootfs[ZPOOL_MAXNAMELEN]; + + return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs, + sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-", + sizeof (bootfs)) != 0); +} + + /* * Given an nvlist of zpool properties to be set, validate that they are * correct, and parse any numeric properties (index, boolean, etc) if they are * specified as strings. */ static nvlist_t * -zpool_validate_properties(libzfs_handle_t *hdl, const char *poolname, +zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, nvlist_t *props, uint64_t version, boolean_t create_or_import, char *errbuf) { nvpair_t *elem; @@ -299,6 +350,8 @@ zpool_validate_properties(libzfs_handle_t *hdl, const char *poolname, uint64_t intval; char *slash; struct stat64 statbuf; + zpool_handle_t *zhp; + nvlist_t *nvroot; if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) { (void) no_memory(hdl); @@ -372,6 +425,29 @@ zpool_validate_properties(libzfs_handle_t *hdl, const char *poolname, (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); goto error; } + + if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "could not open pool '%s'"), poolname); + (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf); + goto error; + } + verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), + ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); + + /* + * bootfs property cannot be set on a disk which has + * been EFI labeled. + */ + if (pool_uses_efi(nvroot)) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "property '%s' not supported on " + "EFI labeled devices"), propname); + (void) zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf); + zpool_close(zhp); + goto error; + } + zpool_close(zhp); break; case ZPOOL_PROP_ALTROOT: @@ -468,7 +544,7 @@ zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval) } version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); - if ((realprops = zpool_validate_properties(zhp->zpool_hdl, + if ((realprops = zpool_valid_proplist(zhp->zpool_hdl, zhp->zpool_name, nvl, version, B_FALSE, errbuf)) == NULL) { nvlist_free(nvl); return (-1); @@ -751,11 +827,14 @@ zpool_get_state(zpool_handle_t *zhp) */ int zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot, - nvlist_t *props) + nvlist_t *props, nvlist_t *fsprops) { zfs_cmd_t zc = { 0 }; + nvlist_t *zc_fsprops = NULL; + nvlist_t *zc_props = NULL; char msg[1024]; char *altroot; + int ret = -1; (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, "cannot create '%s'"), pool); @@ -766,21 +845,45 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot, if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0) return (-1); - if (props && (props = zpool_validate_properties(hdl, pool, props, - SPA_VERSION_1, B_TRUE, msg)) == NULL) - return (-1); - - if (props && zcmd_write_src_nvlist(hdl, &zc, props) != 0) { - nvlist_free(props); - return (-1); + if (props) { + if ((zc_props = zpool_valid_proplist(hdl, pool, props, + SPA_VERSION_1, B_TRUE, msg)) == NULL) { + goto create_failed; + } } + if (fsprops) { + uint64_t zoned; + char *zonestr; + + zoned = ((nvlist_lookup_string(fsprops, + zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) && + strcmp(zonestr, "on") == 0); + + if ((zc_fsprops = zfs_valid_proplist(hdl, + ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) { + goto create_failed; + } + if (!zc_props && + (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) { + goto create_failed; + } + if (nvlist_add_nvlist(zc_props, + ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) { + goto create_failed; + } + } + + if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0) + goto create_failed; + (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name)); - if (zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc) != 0) { + if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) { zcmd_free_nvlists(&zc); - nvlist_free(props); + nvlist_free(zc_props); + nvlist_free(zc_fsprops); switch (errno) { case EBUSY: @@ -842,9 +945,11 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot, zfs_close(zhp); } +create_failed: zcmd_free_nvlists(&zc); - nvlist_free(props); - return (0); + nvlist_free(zc_props); + nvlist_free(zc_fsprops); + return (ret); } /* @@ -920,6 +1025,24 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot) return (zfs_error(hdl, EZFS_BADVERSION, msg)); } + if (pool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot, + ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) { + uint64_t s; + + for (s = 0; s < nspares; s++) { + char *path; + + if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH, + &path) == 0 && pool_uses_efi(spares[s])) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "device '%s' contains an EFI label and " + "cannot be used on root pools."), + zpool_vdev_name(hdl, NULL, spares[s])); + return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg)); + } + } + } + if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) < SPA_VERSION_L2CACHE && nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, @@ -1004,19 +1127,36 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot) * mounted datasets in the pool. */ int -zpool_export(zpool_handle_t *zhp) +zpool_export(zpool_handle_t *zhp, boolean_t force) { zfs_cmd_t zc = { 0 }; + char msg[1024]; if (zpool_remove_zvol_links(zhp) != 0) return (-1); - (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); + (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, + "cannot export '%s'"), zhp->zpool_name); + + (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); + zc.zc_cookie = force; + + if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) { + switch (errno) { + case EXDEV: + zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN, + "use '-f' to override the following errors:\n" + "'%s' has an active shared spare which could be" + " used by other pools once '%s' is exported."), + zhp->zpool_name, zhp->zpool_name); + return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE, + msg)); + default: + return (zpool_standard_error_fmt(zhp->zpool_hdl, errno, + msg)); + } + } - if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) - return (zpool_standard_error_fmt(zhp->zpool_hdl, errno, - dgettext(TEXT_DOMAIN, "cannot export '%s'"), - zhp->zpool_name)); return (0); } @@ -1050,7 +1190,7 @@ zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, } } - ret = zpool_import_props(hdl, config, newname, props); + ret = zpool_import_props(hdl, config, newname, props, B_FALSE); if (props) nvlist_free(props); return (ret); @@ -1064,7 +1204,7 @@ zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, */ int zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, - nvlist_t *props) + nvlist_t *props, boolean_t importfaulted) { zfs_cmd_t zc = { 0 }; char *thename; @@ -1094,7 +1234,7 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) == 0); - if ((props = zpool_validate_properties(hdl, origname, + if ((props = zpool_valid_proplist(hdl, origname, props, version, B_TRUE, errbuf)) == NULL) { return (-1); } else if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) { @@ -1113,6 +1253,7 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, return (-1); } + zc.zc_cookie = (uint64_t)importfaulted; ret = 0; if (zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc) != 0) { char desc[1024]; @@ -1194,7 +1335,7 @@ zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type) */ static nvlist_t * vdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid, - boolean_t *avail_spare, boolean_t *l2cache) + boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log) { uint_t c, children; nvlist_t **child; @@ -1202,6 +1343,7 @@ vdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid, char *path; uint64_t wholedisk = 0; nvlist_t *ret; + uint64_t is_log; verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &theguid) == 0); @@ -1234,16 +1376,30 @@ vdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid, &child, &children) != 0) return (NULL); - for (c = 0; c < children; c++) + for (c = 0; c < children; c++) { if ((ret = vdev_to_nvlist_iter(child[c], search, guid, - avail_spare, l2cache)) != NULL) + avail_spare, l2cache, NULL)) != NULL) { + /* + * The 'is_log' value is only set for the toplevel + * vdev, not the leaf vdevs. So we always lookup the + * log device from the root of the vdev tree (where + * 'log' is non-NULL). + */ + if (log != NULL && + nvlist_lookup_uint64(child[c], + ZPOOL_CONFIG_IS_LOG, &is_log) == 0 && + is_log) { + *log = B_TRUE; + } return (ret); + } + } if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child, &children) == 0) { for (c = 0; c < children; c++) { if ((ret = vdev_to_nvlist_iter(child[c], search, guid, - avail_spare, l2cache)) != NULL) { + avail_spare, l2cache, NULL)) != NULL) { *avail_spare = B_TRUE; return (ret); } @@ -1254,7 +1410,7 @@ vdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid, &child, &children) == 0) { for (c = 0; c < children; c++) { if ((ret = vdev_to_nvlist_iter(child[c], search, guid, - avail_spare, l2cache)) != NULL) { + avail_spare, l2cache, NULL)) != NULL) { *l2cache = B_TRUE; return (ret); } @@ -1266,7 +1422,7 @@ vdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid, nvlist_t * zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare, - boolean_t *l2cache) + boolean_t *l2cache, boolean_t *log) { char buf[MAXPATHLEN]; const char *search; @@ -1289,8 +1445,98 @@ zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare, *avail_spare = B_FALSE; *l2cache = B_FALSE; + if (log != NULL) + *log = B_FALSE; return (vdev_to_nvlist_iter(nvroot, search, guid, avail_spare, - l2cache)); + l2cache, log)); +} + +static int +vdev_online(nvlist_t *nv) +{ + uint64_t ival; + + if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 || + nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 || + nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0) + return (0); + + return (1); +} + +/* + * Get phys_path for a root pool + * Return 0 on success; non-zeron on failure. + */ +int +zpool_get_physpath(zpool_handle_t *zhp, char *physpath) +{ + nvlist_t *vdev_root; + nvlist_t **child; + uint_t count; + int i; + + /* + * Make sure this is a root pool, as phys_path doesn't mean + * anything to a non-root pool. + */ + if (!pool_is_bootable(zhp)) + return (-1); + + verify(nvlist_lookup_nvlist(zhp->zpool_config, + ZPOOL_CONFIG_VDEV_TREE, &vdev_root) == 0); + + if (nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN, + &child, &count) != 0) + return (-2); + + for (i = 0; i < count; i++) { + nvlist_t **child2; + uint_t count2; + char *type; + char *tmppath; + int j; + + if (nvlist_lookup_string(child[i], ZPOOL_CONFIG_TYPE, &type) + != 0) + return (-3); + + if (strcmp(type, VDEV_TYPE_DISK) == 0) { + if (!vdev_online(child[i])) + return (-8); + verify(nvlist_lookup_string(child[i], + ZPOOL_CONFIG_PHYS_PATH, &tmppath) == 0); + (void) strncpy(physpath, tmppath, strlen(tmppath)); + } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0) { + if (nvlist_lookup_nvlist_array(child[i], + ZPOOL_CONFIG_CHILDREN, &child2, &count2) != 0) + return (-4); + + for (j = 0; j < count2; j++) { + if (!vdev_online(child2[j])) + return (-8); + if (nvlist_lookup_string(child2[j], + ZPOOL_CONFIG_PHYS_PATH, &tmppath) != 0) + return (-5); + + if ((strlen(physpath) + strlen(tmppath)) > + MAXNAMELEN) + return (-6); + + if (strlen(physpath) == 0) { + (void) strncpy(physpath, tmppath, + strlen(tmppath)); + } else { + (void) strcat(physpath, " "); + (void) strcat(physpath, tmppath); + } + } + } else { + return (-7); + } + } + + return (0); } /* @@ -1339,7 +1585,8 @@ zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags, dgettext(TEXT_DOMAIN, "cannot online %s"), path); (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); - if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache)) == NULL) + if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, + NULL)) == NULL) return (zfs_error(hdl, EZFS_NODEVICE, msg)); verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); @@ -1348,14 +1595,9 @@ zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags, is_guid_type(zhp, zc.zc_guid, ZPOOL_CONFIG_SPARES) == B_TRUE) return (zfs_error(hdl, EZFS_ISSPARE, msg)); - if (l2cache || - is_guid_type(zhp, zc.zc_guid, ZPOOL_CONFIG_L2CACHE) == B_TRUE) - return (zfs_error(hdl, EZFS_ISL2CACHE, msg)); - zc.zc_cookie = VDEV_STATE_ONLINE; zc.zc_obj = flags; - if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) return (zpool_standard_error(hdl, errno, msg)); @@ -1379,7 +1621,8 @@ zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp) dgettext(TEXT_DOMAIN, "cannot offline %s"), path); (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); - if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache)) == NULL) + if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, + NULL)) == NULL) return (zfs_error(hdl, EZFS_NODEVICE, msg)); verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); @@ -1388,10 +1631,6 @@ zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp) is_guid_type(zhp, zc.zc_guid, ZPOOL_CONFIG_SPARES) == B_TRUE) return (zfs_error(hdl, EZFS_ISSPARE, msg)); - if (l2cache || - is_guid_type(zhp, zc.zc_guid, ZPOOL_CONFIG_L2CACHE) == B_TRUE) - return (zfs_error(hdl, EZFS_ISL2CACHE, msg)); - zc.zc_cookie = VDEV_STATE_OFFLINE; zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0; @@ -1508,13 +1747,14 @@ zpool_vdev_attach(zpool_handle_t *zhp, char msg[1024]; int ret; nvlist_t *tgt; - boolean_t avail_spare, l2cache; - uint64_t val, is_log; - char *path; + boolean_t avail_spare, l2cache, islog; + uint64_t val; + char *path, *newname; nvlist_t **child; uint_t children; nvlist_t *config_root; libzfs_handle_t *hdl = zhp->zpool_hdl; + boolean_t rootpool = pool_is_bootable(zhp); if (replacing) (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, @@ -1523,8 +1763,19 @@ zpool_vdev_attach(zpool_handle_t *zhp, (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, "cannot attach %s to %s"), new_disk, old_disk); + /* + * If this is a root pool, make sure that we're not attaching an + * EFI labeled device. + */ + if (rootpool && pool_uses_efi(nvroot)) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "EFI labeled devices are not supported on root pools.")); + return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg)); + } + (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); - if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache)) == 0) + if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache, + &islog)) == 0) return (zfs_error(hdl, EZFS_NODEVICE, msg)); if (avail_spare) @@ -1546,17 +1797,21 @@ zpool_vdev_attach(zpool_handle_t *zhp, verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0); + if ((newname = zpool_vdev_name(NULL, NULL, child[0])) == NULL) + return (-1); + /* * If the target is a hot spare that has been swapped in, we can only * replace it with another hot spare. */ if (replacing && nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 && - nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 && - (zpool_find_vdev(zhp, path, &avail_spare, &l2cache) == NULL || - !avail_spare) && is_replacing_spare(config_root, tgt, 1)) { + (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache, + NULL) == NULL || !avail_spare) && + is_replacing_spare(config_root, tgt, 1)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "can only be replaced by another hot spare")); + free(newname); return (zfs_error(hdl, EZFS_BADTARGET, msg)); } @@ -1566,13 +1821,17 @@ zpool_vdev_attach(zpool_handle_t *zhp, */ if (replacing && nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 && - zpool_find_vdev(zhp, path, &avail_spare, &l2cache) != NULL && - avail_spare && is_replacing_spare(config_root, tgt, 0)) { + zpool_find_vdev(zhp, newname, &avail_spare, + &l2cache, NULL) != NULL && avail_spare && + is_replacing_spare(config_root, tgt, 0)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "device has already been replaced with a spare")); + free(newname); return (zfs_error(hdl, EZFS_BADTARGET, msg)); } + free(newname); + if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0) return (-1); @@ -1580,8 +1839,19 @@ zpool_vdev_attach(zpool_handle_t *zhp, zcmd_free_nvlists(&zc); - if (ret == 0) + if (ret == 0) { + if (rootpool) { + /* + * XXX - This should be removed once we can + * automatically install the bootblocks on the + * newly attached disk. + */ + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Please " + "be sure to invoke %s to make '%s' bootable.\n"), + BOOTCMD, new_disk); + } return (0); + } switch (errno) { case ENOTSUP: @@ -1589,10 +1859,7 @@ zpool_vdev_attach(zpool_handle_t *zhp, * Can't attach to or replace this type of vdev. */ if (replacing) { - is_log = B_FALSE; - (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_LOG, - &is_log); - if (is_log) + if (islog) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot replace a log with a spare")); else @@ -1669,7 +1936,8 @@ zpool_vdev_detach(zpool_handle_t *zhp, const char *path) dgettext(TEXT_DOMAIN, "cannot detach %s"), path); (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); - if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache)) == 0) + if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, + NULL)) == 0) return (zfs_error(hdl, EZFS_NODEVICE, msg)); if (avail_spare) @@ -1725,7 +1993,8 @@ zpool_vdev_remove(zpool_handle_t *zhp, const char *path) dgettext(TEXT_DOMAIN, "cannot remove %s"), path); (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); - if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache)) == 0) + if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, + NULL)) == 0) return (zfs_error(hdl, EZFS_NODEVICE, msg)); if (!avail_spare && !l2cache) { @@ -1767,7 +2036,7 @@ zpool_clear(zpool_handle_t *zhp, const char *path) (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); if (path) { if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, - &l2cache)) == 0) + &l2cache, NULL)) == 0) return (zfs_error(hdl, EZFS_NODEVICE, msg)); /* @@ -2503,6 +2772,38 @@ zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj, */ #define NEW_START_BLOCK 256 +/* + * Read the EFI label from the config, if a label does not exist then + * pass back the error to the caller. If the caller has passed a non-NULL + * diskaddr argument then we set it to the starting address of the EFI + * partition. + */ +static int +read_efi_label(nvlist_t *config, diskaddr_t *sb) +{ + char *path; + int fd; + char diskname[MAXPATHLEN]; + int err = -1; + + if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0) + return (err); + + (void) snprintf(diskname, sizeof (diskname), "%s%s", RDISK_ROOT, + strrchr(path, '/')); + if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) { + struct dk_gpt *vtoc; + + if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) { + if (sb != NULL) + *sb = vtoc->efi_parts[0].p_start; + efi_free(vtoc); + } + (void) close(fd); + } + return (err); +} + /* * determine where a partition starts on a disk in the current * configuration @@ -2512,10 +2813,7 @@ find_start_block(nvlist_t *config) { nvlist_t **child; uint_t c, children; - char *path; diskaddr_t sb = MAXOFFSET_T; - int fd; - char diskname[MAXPATHLEN]; uint64_t wholedisk; if (nvlist_lookup_nvlist_array(config, @@ -2525,21 +2823,8 @@ find_start_block(nvlist_t *config) &wholedisk) != 0 || !wholedisk) { return (MAXOFFSET_T); } - if (nvlist_lookup_string(config, - ZPOOL_CONFIG_PATH, &path) != 0) { - return (MAXOFFSET_T); - } - - (void) snprintf(diskname, sizeof (diskname), "%s%s", - RDISK_ROOT, strrchr(path, '/')); - if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) { - struct dk_gpt *vtoc; - if (efi_alloc_and_read(fd, &vtoc) >= 0) { - sb = vtoc->efi_parts[0].p_start; - efi_free(vtoc); - } - (void) close(fd); - } + if (read_efi_label(config, &sb) < 0) + sb = MAXOFFSET_T; return (sb); } @@ -2574,6 +2859,13 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name) if (zhp) { nvlist_t *nvroot; + if (pool_is_bootable(zhp)) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "EFI labeled devices are not supported on root " + "pools.")); + return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf)); + } + verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); diff --git a/zfs/lib/libzfs/libzfs_sendrecv.c b/zfs/lib/libzfs/libzfs_sendrecv.c index 2bef06159..a3ed5cea8 100644 --- a/zfs/lib/libzfs/libzfs_sendrecv.c +++ b/zfs/lib/libzfs/libzfs_sendrecv.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_sendrecv.c 1.7 08/04/23 SMI" - #include #include #include @@ -51,6 +49,9 @@ #include /* XXX */ +static int zfs_receive_impl(libzfs_handle_t *, const char *, recvflags_t, + int, avl_tree_t *, char **); + /* * Routines for dealing with the AVL tree of fs-nvlists */ @@ -166,6 +167,7 @@ typedef struct send_data { uint64_t parent_fromsnap_guid; nvlist_t *parent_snaps; nvlist_t *fss; + nvlist_t *snapprops; const char *fromsnap; const char *tosnap; @@ -182,6 +184,7 @@ typedef struct send_data { * * "props" -> { name -> value (only if set here) } * "snaps" -> { name (lastname) -> number (guid) } + * "snapprops" -> { name (lastname) -> { name -> value } } * * "origin" -> number (guid) (if clone) * "sent" -> boolean (not on-disk) @@ -192,12 +195,15 @@ typedef struct send_data { */ } send_data_t; +static void send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv); + static int send_iterate_snap(zfs_handle_t *zhp, void *arg) { send_data_t *sd = arg; uint64_t guid = zhp->zfs_dmustats.dds_guid; char *snapname; + nvlist_t *nv; snapname = strrchr(zhp->zfs_name, '@')+1; @@ -212,6 +218,11 @@ send_iterate_snap(zfs_handle_t *zhp, void *arg) sd->parent_fromsnap_guid = guid; } + VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0)); + send_iterate_prop(zhp, nv); + VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv)); + nvlist_free(nv); + zfs_close(zhp); return (0); } @@ -235,6 +246,8 @@ send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv) uint64_t value; verify(nvlist_lookup_uint64(propnv, ZPROP_VALUE, &value) == 0); + if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) + continue; } else { char *source; if (nvlist_lookup_string(propnv, @@ -292,9 +305,12 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg) /* iterate over snaps, and set sd->parent_fromsnap_guid */ sd->parent_fromsnap_guid = 0; VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0)); + VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0)); (void) zfs_iter_snapshots(zhp, send_iterate_snap, sd); VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps)); + VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops)); nvlist_free(sd->parent_snaps); + nvlist_free(sd->snapprops); /* add this fs to nvlist */ (void) snprintf(guidstring, sizeof (guidstring), @@ -867,7 +883,8 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname, zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET); if (zhp == NULL) return (-1); - clp = changelist_gather(zhp, ZFS_PROP_NAME, flags.force ? MS_FORCE : 0); + clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, + flags.force ? MS_FORCE : 0); zfs_close(zhp); if (clp == NULL) return (-1); @@ -938,7 +955,8 @@ recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen, zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET); if (zhp == NULL) return (-1); - clp = changelist_gather(zhp, ZFS_PROP_NAME, flags.force ? MS_FORCE : 0); + clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, + flags.force ? MS_FORCE : 0); zfs_close(zhp); if (clp == NULL) return (-1); @@ -1180,7 +1198,7 @@ again: snapelem; snapelem = nextsnapelem) { uint64_t thisguid; char *stream_snapname; - nvlist_t *found; + nvlist_t *found, *props; nextsnapelem = nvlist_next_nvpair(snaps, snapelem); @@ -1209,6 +1227,22 @@ again: stream_nvfs = found; + if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops", + &props) && 0 == nvlist_lookup_nvlist(props, + stream_snapname, &props)) { + zfs_cmd_t zc = { 0 }; + + zc.zc_cookie = B_TRUE; /* clear current props */ + (void) snprintf(zc.zc_name, sizeof (zc.zc_name), + "%s@%s", fsname, nvpair_name(snapelem)); + if (zcmd_write_src_nvlist(hdl, &zc, + props) == 0) { + (void) zfs_ioctl(hdl, + ZFS_IOC_SET_PROP, &zc); + zcmd_free_nvlists(&zc); + } + } + /* check for different snapname */ if (strcmp(nvpair_name(snapelem), stream_snapname) != 0) { @@ -1314,7 +1348,8 @@ again: static int zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname, - recvflags_t flags, dmu_replay_record_t *drr, zio_cksum_t *zc) + recvflags_t flags, dmu_replay_record_t *drr, zio_cksum_t *zc, + char **top_zfs) { nvlist_t *stream_nv = NULL; avl_tree_t *stream_avl = NULL; @@ -1426,7 +1461,8 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname, * zfs_receive_one() will take care of it (ie, * recv_skip() and return 0). */ - error = zfs_receive(hdl, destname, flags, fd, stream_avl); + error = zfs_receive_impl(hdl, destname, flags, fd, + stream_avl, top_zfs); if (error == ENODATA) { error = 0; break; @@ -1492,7 +1528,7 @@ recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap) case DRR_WRITE: if (byteswap) { drr->drr_u.drr_write.drr_length = - BSWAP_32(drr->drr_u.drr_write.drr_length); + BSWAP_64(drr->drr_u.drr_write.drr_length); } (void) recv_read(hdl, fd, buf, drr->drr_u.drr_write.drr_length, B_FALSE, NULL); @@ -1517,7 +1553,8 @@ recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap) static int zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, recvflags_t flags, dmu_replay_record_t *drr, - dmu_replay_record_t *drr_noswap, avl_tree_t *stream_avl) + dmu_replay_record_t *drr_noswap, avl_tree_t *stream_avl, + char **top_zfs) { zfs_cmd_t zc = { 0 }; time_t begin_time; @@ -1530,6 +1567,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, boolean_t stream_wantsnewfs; uint64_t parent_snapguid = 0; prop_changelist_t *clp = NULL; + nvlist_t *snapprops_nvlist = NULL; begin_time = time(NULL); @@ -1537,7 +1575,9 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, "cannot receive")); if (stream_avl != NULL) { - nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid, NULL); + char *snapname; + nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid, + &snapname); nvlist_t *props; int ret; @@ -1555,6 +1595,11 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, if (err) nvlist_free(props); + if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) { + VERIFY(0 == nvlist_lookup_nvlist(props, + snapname, &snapprops_nvlist)); + } + if (ret != 0) return (-1); } @@ -1720,7 +1765,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM && stream_wantsnewfs) { /* We can't do online recv in this case */ - clp = changelist_gather(zhp, ZFS_PROP_NAME, 0); + clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0); if (clp == NULL) { zcmd_free_nvlists(&zc); return (-1); @@ -1787,6 +1832,18 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc); ioctl_errno = errno; + zcmd_free_nvlists(&zc); + + if (err == 0 && snapprops_nvlist) { + zfs_cmd_t zc2 = { 0 }; + + (void) strcpy(zc2.zc_name, zc.zc_value); + if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) { + (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2); + zcmd_free_nvlists(&zc2); + } + } + if (err && (ioctl_errno == ENOENT || ioctl_errno == ENODEV)) { /* * It may be that this snapshot already exists, @@ -1822,7 +1879,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, *cp = '@'; } - zcmd_free_nvlists(&zc); if (ioctl_err != 0) { switch (ioctl_errno) { @@ -1881,18 +1937,24 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, *cp = '\0'; h = zfs_open(hdl, zc.zc_value, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); - *cp = '@'; if (h != NULL) { if (h->zfs_type == ZFS_TYPE_VOLUME) { + *cp = '@'; err = zvol_create_link(hdl, h->zfs_name); if (err == 0 && ioctl_err == 0) err = zvol_create_link(hdl, zc.zc_value); } else if (newfs) { - err = zfs_mount(h, NULL, 0); + /* + * Track the first/top of hierarchy fs, + * for mounting and sharing later. + */ + if (top_zfs && *top_zfs == NULL) + *top_zfs = zfs_strdup(hdl, zc.zc_value); } zfs_close(h); } + *cp = '@'; } if (clp) { @@ -1920,15 +1982,9 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, return (0); } -/* - * Restores a backup of tosnap from the file descriptor specified by infd. - * Return 0 on total success, -2 if some things couldn't be - * destroyed/renamed/promoted, -1 if some things couldn't be received. - * (-1 will override -2). - */ -int -zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags, - int infd, avl_tree_t *stream_avl) +static int +zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags, + int infd, avl_tree_t *stream_avl, char **top_zfs) { int err; dmu_replay_record_t drr, drr_noswap; @@ -1994,10 +2050,10 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags, if (drrb->drr_version == DMU_BACKUP_STREAM_VERSION) { return (zfs_receive_one(hdl, infd, tosnap, flags, - &drr, &drr_noswap, stream_avl)); + &drr, &drr_noswap, stream_avl, top_zfs)); } else if (drrb->drr_version == DMU_BACKUP_HEADER_VERSION) { return (zfs_receive_package(hdl, infd, tosnap, flags, - &drr, &zcksum)); + &drr, &zcksum, top_zfs)); } else { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "stream is unsupported version %llu"), @@ -2005,3 +2061,42 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags, return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); } } + +/* + * Restores a backup of tosnap from the file descriptor specified by infd. + * Return 0 on total success, -2 if some things couldn't be + * destroyed/renamed/promoted, -1 if some things couldn't be received. + * (-1 will override -2). + */ +int +zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags, + int infd, avl_tree_t *stream_avl) +{ + char *top_zfs = NULL; + int err; + + err = zfs_receive_impl(hdl, tosnap, flags, infd, stream_avl, &top_zfs); + + if (err == 0 && top_zfs) { + zfs_handle_t *zhp; + prop_changelist_t *clp; + + zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM); + if (zhp != NULL) { + clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, + CL_GATHER_MOUNT_ALWAYS, 0); + zfs_close(zhp); + if (clp != NULL) { + /* mount and share received datasets */ + err = changelist_postfix(clp); + changelist_free(clp); + } + } + if (zhp == NULL || clp == NULL || err) + err = -1; + } + if (top_zfs) + free(top_zfs); + + return (err); +} diff --git a/zfs/lib/libzfs/libzfs_status.c b/zfs/lib/libzfs/libzfs_status.c index e7f9aa6a9..c7eb04e74 100644 --- a/zfs/lib/libzfs/libzfs_status.c +++ b/zfs/lib/libzfs/libzfs_status.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_status.c 1.7 07/06/29 SMI" - /* * This file contains the functions which analyze the status of a pool. This * include both the status of an active pool, as well as the status exported @@ -62,7 +60,10 @@ static char *zfs_msgid_table[] = { "ZFS-8000-8A", "ZFS-8000-9P", "ZFS-8000-A5", - "ZFS-8000-EY" + "ZFS-8000-EY", + "ZFS-8000-HC", + "ZFS-8000-JQ", + "ZFS-8000-K4", }; #define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0])) @@ -169,6 +170,7 @@ check_status(nvlist_t *config, boolean_t isimport) uint64_t nerr; uint64_t version; uint64_t stateval; + uint64_t suspended; uint64_t hostid = 0; verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, @@ -202,6 +204,24 @@ check_status(nvlist_t *config, boolean_t isimport) vs->vs_aux == VDEV_AUX_BAD_GUID_SUM) return (ZPOOL_STATUS_BAD_GUID_SUM); + /* + * Check whether the pool has suspended due to failed I/O. + */ + if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED, + &suspended) == 0) { + if (suspended == ZIO_FAILURE_MODE_CONTINUE) + return (ZPOOL_STATUS_IO_FAILURE_CONTINUE); + return (ZPOOL_STATUS_IO_FAILURE_WAIT); + } + + /* + * Could not read a log. + */ + if (vs->vs_state == VDEV_STATE_CANT_OPEN && + vs->vs_aux == VDEV_AUX_BAD_LOG) { + return (ZPOOL_STATUS_BAD_LOG); + } + /* * Bad devices in non-replicated config. */ diff --git a/zfs/lib/libzfs/libzfs_util.c b/zfs/lib/libzfs/libzfs_util.c index 54acc26f7..54de0f4b5 100644 --- a/zfs/lib/libzfs/libzfs_util.c +++ b/zfs/lib/libzfs/libzfs_util.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)libzfs_util.c 1.29 08/04/01 SMI" - /* * Internal utility routines for the ZFS library. */ @@ -206,6 +204,12 @@ libzfs_error_description(libzfs_handle_t *hdl) case EZFS_VDEVNOTSUP: return (dgettext(TEXT_DOMAIN, "vdev specification is not " "supported")); + case EZFS_NOTSUP: + return (dgettext(TEXT_DOMAIN, "operation not supported " + "on this dataset")); + case EZFS_ACTIVE_SPARE: + return (dgettext(TEXT_DOMAIN, "pool has active shared spare " + "device")); case EZFS_UNKNOWN: return (dgettext(TEXT_DOMAIN, "unknown error")); default: @@ -408,7 +412,7 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) case EBUSY: zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy")); - zfs_verror(hdl, EZFS_EXISTS, fmt, ap); + zfs_verror(hdl, EZFS_BUSY, fmt, ap); break; case ENXIO: @@ -587,6 +591,7 @@ libzfs_fini(libzfs_handle_t *hdl) zfs_uninit_libshare(hdl); if (hdl->libzfs_log_str) (void) free(hdl->libzfs_log_str); + zpool_free_handles(hdl); namespace_clear(hdl); free(hdl); } @@ -603,6 +608,12 @@ zfs_get_handle(zfs_handle_t *zhp) return (zhp->zfs_hdl); } +zpool_handle_t * +zfs_get_pool_handle(const zfs_handle_t *zhp) +{ + return (zhp->zpool_hdl); +} + /* * Given a name, determine whether or not it's a valid path * (starts with '/' or "./"). If so, walk the mnttab trying @@ -1173,6 +1184,51 @@ error: return (-1); } +static int +addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp, + zfs_type_t type) +{ + int prop; + zprop_list_t *entry; + + prop = zprop_name_to_prop(propname, type); + + if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type)) + prop = ZPROP_INVAL; + + /* + * When no property table entry can be found, return failure if + * this is a pool property or if this isn't a user-defined + * dataset property, + */ + if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL || + !zfs_prop_user(propname))) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "invalid property '%s'"), propname); + return (zfs_error(hdl, EZFS_BADPROP, + dgettext(TEXT_DOMAIN, "bad property list"))); + } + + if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL) + return (-1); + + entry->pl_prop = prop; + if (prop == ZPROP_INVAL) { + if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == NULL) { + free(entry); + return (-1); + } + entry->pl_width = strlen(propname); + } else { + entry->pl_width = zprop_width(prop, &entry->pl_fixed, + type); + } + + *listp = entry; + + return (0); +} + /* * Given a comma-separated list of properties, construct a property list * containing both user-defined and native properties. This function will @@ -1183,15 +1239,7 @@ int zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp, zfs_type_t type) { - size_t len; - char *s, *p; - char c; - int prop; - zprop_list_t *entry; - zprop_list_t **last; - *listp = NULL; - last = listp; /* * If 'all' is specified, return a NULL list. @@ -1213,13 +1261,16 @@ zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp, * It would be nice to use getsubopt() here, but the inclusion of column * aliases makes this more effort than it's worth. */ - s = props; - while (*s != '\0') { - if ((p = strchr(s, ',')) == NULL) { - len = strlen(s); - p = s + len; + while (*props != '\0') { + size_t len; + char *p; + char c; + + if ((p = strchr(props, ',')) == NULL) { + len = strlen(props); + p = props + len; } else { - len = p - s; + len = p - props; } /* @@ -1235,48 +1286,31 @@ zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp, /* * Check all regular property names. */ - c = s[len]; - s[len] = '\0'; - prop = zprop_name_to_prop(s, type); + c = props[len]; + props[len] = '\0'; - if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type)) - prop = ZPROP_INVAL; + if (strcmp(props, "space") == 0) { + static char *spaceprops[] = { + "name", "avail", "used", "usedbysnapshots", + "usedbydataset", "usedbyrefreservation", + "usedbychildren", NULL + }; + int i; - /* - * When no property table entry can be found, return failure if - * this is a pool property or if this isn't a user-defined - * dataset property, - */ - if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL || - !zfs_prop_user(s))) { - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "invalid property '%s'"), s); - return (zfs_error(hdl, EZFS_BADPROP, - dgettext(TEXT_DOMAIN, "bad property list"))); - } - - if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL) - return (-1); - - entry->pl_prop = prop; - if (prop == ZPROP_INVAL) { - if ((entry->pl_user_prop = zfs_strdup(hdl, s)) - == NULL) { - free(entry); - return (-1); + for (i = 0; spaceprops[i]; i++) { + if (addlist(hdl, spaceprops[i], listp, type)) + return (-1); + listp = &(*listp)->pl_next; } - entry->pl_width = strlen(s); } else { - entry->pl_width = zprop_width(prop, &entry->pl_fixed, - type); + if (addlist(hdl, props, listp, type)) + return (-1); + listp = &(*listp)->pl_next; } - *last = entry; - last = &entry->pl_next; - - s = p; + props = p; if (c == ',') - s++; + props++; } return (0); diff --git a/zfs/lib/libzpool/arc.c b/zfs/lib/libzpool/arc.c index 8d091b7ce..73aecb285 100644 --- a/zfs/lib/libzpool/arc.c +++ b/zfs/lib/libzpool/arc.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)arc.c 1.44 08/03/20 SMI" - /* * DVA-based Adjustable Replacement Cache * @@ -125,6 +123,7 @@ #include #include #include +#include #ifdef _KERNEL #include #include @@ -140,7 +139,7 @@ static uint8_t arc_thread_exit; extern int zfs_write_limit_shift; extern uint64_t zfs_write_limit_max; -extern uint64_t zfs_write_limit_inflated; +extern kmutex_t zfs_write_limit_lock; #define ARC_REDUCE_DNLC_PERCENT 3 uint_t arc_reduce_dnlc_percent = ARC_REDUCE_DNLC_PERCENT; @@ -161,12 +160,18 @@ static int arc_min_prefetch_lifespan; static int arc_dead; +/* + * The arc has filled available memory and has now warmed up. + */ +static boolean_t arc_warm; + /* * These tunables are for performance analysis. */ uint64_t zfs_arc_max; uint64_t zfs_arc_min; uint64_t zfs_arc_meta_limit = 0; +int zfs_mdcomp_disable = 0; /* * Note that buffers can be in one of 6 states: @@ -386,7 +391,6 @@ typedef struct arc_callback arc_callback_t; struct arc_callback { void *acb_private; arc_done_func_t *acb_done; - arc_byteswap_func_t *acb_byteswap; arc_buf_t *acb_buf; zio_t *acb_zio_dummy; arc_callback_t *acb_next; @@ -464,11 +468,10 @@ static void arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes); #define ARC_BUF_AVAILABLE (1 << 13) /* block not in active use */ #define ARC_INDIRECT (1 << 14) /* this is an indirect block */ #define ARC_FREE_IN_PROGRESS (1 << 15) /* hdr about to be freed */ -#define ARC_DONT_L2CACHE (1 << 16) /* originated by prefetch */ -#define ARC_L2_READING (1 << 17) /* L2ARC read in progress */ -#define ARC_L2_WRITING (1 << 18) /* L2ARC write in progress */ -#define ARC_L2_EVICTED (1 << 19) /* evicted during I/O */ -#define ARC_L2_WRITE_HEAD (1 << 20) /* head of write list */ +#define ARC_L2_WRITING (1 << 16) /* L2ARC write in progress */ +#define ARC_L2_EVICTED (1 << 17) /* evicted during I/O */ +#define ARC_L2_WRITE_HEAD (1 << 18) /* head of write list */ +#define ARC_STORED (1 << 19) /* has been store()d to */ #define HDR_IN_HASH_TABLE(hdr) ((hdr)->b_flags & ARC_IN_HASH_TABLE) #define HDR_IO_IN_PROGRESS(hdr) ((hdr)->b_flags & ARC_IO_IN_PROGRESS) @@ -476,8 +479,9 @@ static void arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes); #define HDR_FREED_IN_READ(hdr) ((hdr)->b_flags & ARC_FREED_IN_READ) #define HDR_BUF_AVAILABLE(hdr) ((hdr)->b_flags & ARC_BUF_AVAILABLE) #define HDR_FREE_IN_PROGRESS(hdr) ((hdr)->b_flags & ARC_FREE_IN_PROGRESS) -#define HDR_DONT_L2CACHE(hdr) ((hdr)->b_flags & ARC_DONT_L2CACHE) -#define HDR_L2_READING(hdr) ((hdr)->b_flags & ARC_L2_READING) +#define HDR_L2CACHE(hdr) ((hdr)->b_flags & ARC_L2CACHE) +#define HDR_L2_READING(hdr) ((hdr)->b_flags & ARC_IO_IN_PROGRESS && \ + (hdr)->b_l2hdr != NULL) #define HDR_L2_WRITING(hdr) ((hdr)->b_flags & ARC_L2_WRITING) #define HDR_L2_EVICTED(hdr) ((hdr)->b_flags & ARC_L2_EVICTED) #define HDR_L2_WRITE_HEAD(hdr) ((hdr)->b_flags & ARC_L2_WRITE_HEAD) @@ -526,7 +530,6 @@ uint64_t zfs_crc64_table[256]; #define L2ARC_WRITE_SIZE (8 * 1024 * 1024) /* initial write max */ #define L2ARC_HEADROOM 4 /* num of writes */ -#define L2ARC_FEED_DELAY 180 /* starting grace */ #define L2ARC_FEED_SECS 1 /* caching interval */ #define l2arc_writes_sent ARCSTAT(arcstat_l2_writes_sent) @@ -536,6 +539,7 @@ uint64_t zfs_crc64_table[256]; * L2ARC Performance Tunables */ uint64_t l2arc_write_max = L2ARC_WRITE_SIZE; /* default max write size */ +uint64_t l2arc_write_boost = L2ARC_WRITE_SIZE; /* extra write during warmup */ uint64_t l2arc_headroom = L2ARC_HEADROOM; /* number of dev writes */ uint64_t l2arc_feed_secs = L2ARC_FEED_SECS; /* interval seconds */ boolean_t l2arc_noprefetch = B_TRUE; /* don't cache prefetch bufs */ @@ -548,6 +552,7 @@ typedef struct l2arc_dev { spa_t *l2ad_spa; /* spa */ uint64_t l2ad_hand; /* next write location */ uint64_t l2ad_write; /* desired write size, bytes */ + uint64_t l2ad_boost; /* warmup write boost, bytes */ uint64_t l2ad_start; /* first addr on device */ uint64_t l2ad_end; /* last addr on device */ uint64_t l2ad_evict; /* last addr eviction reached */ @@ -602,7 +607,7 @@ static void l2arc_hdr_stat_add(void); static void l2arc_hdr_stat_remove(void); static uint64_t -buf_hash(spa_t *spa, dva_t *dva, uint64_t birth) +buf_hash(spa_t *spa, const dva_t *dva, uint64_t birth) { uintptr_t spav = (uintptr_t)spa; uint8_t *vdva = (uint8_t *)dva; @@ -630,7 +635,7 @@ buf_hash(spa_t *spa, dva_t *dva, uint64_t birth) ((buf)->b_birth == birth) && ((buf)->b_spa == spa) static arc_buf_hdr_t * -buf_hash_find(spa_t *spa, dva_t *dva, uint64_t birth, kmutex_t **lockp) +buf_hash_find(spa_t *spa, const dva_t *dva, uint64_t birth, kmutex_t **lockp) { uint64_t idx = BUF_HASH_INDEX(spa, dva, birth); kmutex_t *hash_lock = BUF_HASH_LOCK(idx); @@ -755,6 +760,17 @@ hdr_cons(void *vbuf, void *unused, int kmflag) return (0); } +/* ARGSUSED */ +static int +buf_cons(void *vbuf, void *unused, int kmflag) +{ + arc_buf_t *buf = vbuf; + + bzero(buf, sizeof (arc_buf_t)); + rw_init(&buf->b_lock, NULL, RW_DEFAULT, NULL); + return (0); +} + /* * Destructor callback - called when a cached buf is * no longer required. @@ -772,6 +788,15 @@ hdr_dest(void *vbuf, void *unused) ARCSTAT_INCR(arcstat_hdr_size, -HDR_SIZE); } +/* ARGSUSED */ +static void +buf_dest(void *vbuf, void *unused) +{ + arc_buf_t *buf = vbuf; + + rw_destroy(&buf->b_lock); +} + /* * Reclaim callback -- invoked when memory is low. */ @@ -815,7 +840,7 @@ retry: hdr_cache = kmem_cache_create("arc_buf_hdr_t", sizeof (arc_buf_hdr_t), 0, hdr_cons, hdr_dest, hdr_recl, NULL, NULL, 0); buf_cache = kmem_cache_create("arc_buf_t", sizeof (arc_buf_t), - 0, NULL, NULL, NULL, NULL, NULL, 0); + 0, buf_cons, buf_dest, NULL, NULL, NULL, 0); for (i = 0; i < 256; i++) for (ct = zfs_crc64_table + i, *ct = i, j = 8; j > 0; j--) @@ -934,7 +959,7 @@ add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) ASSERT3U(*size, >=, delta); atomic_add_64(size, -delta); mutex_exit(&ab->b_state->arcs_mtx); - /* remove the prefetch flag is we get a reference */ + /* remove the prefetch flag if we get a reference */ if (ab->b_flags & ARC_PREFETCH) ab->b_flags &= ~ARC_PREFETCH; } @@ -1147,28 +1172,21 @@ arc_buf_add_ref(arc_buf_t *buf, void* tag) kmutex_t *hash_lock; /* - * Check to see if this buffer is currently being evicted via - * arc_do_user_evicts(). + * Check to see if this buffer is evicted. Callers + * must verify b_data != NULL to know if the add_ref + * was successful. */ - mutex_enter(&arc_eviction_mtx); - hdr = buf->b_hdr; - if (hdr == NULL) { - mutex_exit(&arc_eviction_mtx); - return; - } - hash_lock = HDR_LOCK(hdr); - mutex_exit(&arc_eviction_mtx); - - mutex_enter(hash_lock); + rw_enter(&buf->b_lock, RW_READER); if (buf->b_data == NULL) { - /* - * This buffer is evicted. - */ - mutex_exit(hash_lock); + rw_exit(&buf->b_lock); return; } + hdr = buf->b_hdr; + ASSERT(hdr != NULL); + hash_lock = HDR_LOCK(hdr); + mutex_enter(hash_lock); + rw_exit(&buf->b_lock); - ASSERT(buf->b_hdr == hdr); ASSERT(hdr->b_state == arc_mru || hdr->b_state == arc_mfu); add_reference(hdr, hash_lock, tag); arc_access(hdr, hash_lock); @@ -1264,6 +1282,7 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr) ASSERT(refcount_is_zero(&hdr->b_refcnt)); ASSERT3P(hdr->b_state, ==, arc_anon); ASSERT(!HDR_IO_IN_PROGRESS(hdr)); + ASSERT(!(hdr->b_flags & ARC_STORED)); if (hdr->b_l2hdr != NULL) { if (!MUTEX_HELD(&l2arc_buflist_mtx)) { @@ -1273,11 +1292,15 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr) * a FREE_IN_PROGRESS flag is given to arc_free() to * give it priority. l2arc_evict() can't destroy this * header while we are waiting on l2arc_buflist_mtx. + * + * The hdr may be removed from l2ad_buflist before we + * grab l2arc_buflist_mtx, so b_l2hdr is rechecked. */ mutex_enter(&l2arc_buflist_mtx); - ASSERT(hdr->b_l2hdr != NULL); - - list_remove(hdr->b_l2hdr->b_dev->l2ad_buflist, hdr); + if (hdr->b_l2hdr != NULL) { + list_remove(hdr->b_l2hdr->b_dev->l2ad_buflist, + hdr); + } mutex_exit(&l2arc_buflist_mtx); } else { list_remove(hdr->b_l2hdr->b_dev->l2ad_buflist, hdr); @@ -1300,12 +1323,14 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr) if (buf->b_efunc) { mutex_enter(&arc_eviction_mtx); + rw_enter(&buf->b_lock, RW_WRITER); ASSERT(buf->b_hdr != NULL); arc_buf_destroy(hdr->b_buf, FALSE, FALSE); hdr->b_buf = buf->b_next; buf->b_hdr = &arc_eviction_hdr; buf->b_next = arc_eviction_list; arc_eviction_list = buf; + rw_exit(&buf->b_lock); mutex_exit(&arc_eviction_mtx); } else { arc_buf_destroy(hdr->b_buf, FALSE, TRUE); @@ -1454,6 +1479,10 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle, ASSERT(ab->b_datacnt > 0); while (ab->b_buf) { arc_buf_t *buf = ab->b_buf; + if (!rw_tryenter(&buf->b_lock, RW_WRITER)) { + missed += 1; + break; + } if (buf->b_data) { bytes_evicted += ab->b_size; if (recycle && ab->b_type == type && @@ -1472,17 +1501,20 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle, buf->b_next = arc_eviction_list; arc_eviction_list = buf; mutex_exit(&arc_eviction_mtx); + rw_exit(&buf->b_lock); } else { + rw_exit(&buf->b_lock); arc_buf_destroy(buf, buf->b_data == stolen, TRUE); } } - ASSERT(ab->b_datacnt == 0); - arc_change_state(evicted_state, ab, hash_lock); - ASSERT(HDR_IN_HASH_TABLE(ab)); - ab->b_flags |= ARC_IN_HASH_TABLE; - ab->b_flags &= ~ARC_BUF_AVAILABLE; - DTRACE_PROBE1(arc__evict, arc_buf_hdr_t *, ab); + if (ab->b_datacnt == 0) { + arc_change_state(evicted_state, ab, hash_lock); + ASSERT(HDR_IN_HASH_TABLE(ab)); + ab->b_flags |= ARC_IN_HASH_TABLE; + ab->b_flags &= ~ARC_BUF_AVAILABLE; + DTRACE_PROBE1(arc__evict, arc_buf_hdr_t *, ab); + } if (!have_lock) mutex_exit(hash_lock); if (bytes >= 0 && bytes_evicted >= bytes) @@ -1668,7 +1700,9 @@ arc_do_user_evicts(void) while (arc_eviction_list != NULL) { arc_buf_t *buf = arc_eviction_list; arc_eviction_list = buf->b_next; + rw_enter(&buf->b_lock, RW_WRITER); buf->b_hdr = NULL; + rw_exit(&buf->b_lock); mutex_exit(&arc_eviction_mtx); if (buf->b_efunc != NULL) @@ -1884,6 +1918,7 @@ arc_reclaim_thread(void) growtime = lbolt + (arc_grow_retry * hz); arc_kmem_reap_now(last_reclaim); + arc_warm = B_TRUE; } else if (arc_no_grow && lbolt >= growtime) { arc_no_grow = FALSE; @@ -2281,15 +2316,19 @@ arc_read_done(zio_t *zio) (found == hdr && DVA_EQUAL(&hdr->b_dva, BP_IDENTITY(zio->io_bp))) || (found == hdr && HDR_L2_READING(hdr))); - hdr->b_flags &= ~(ARC_L2_READING|ARC_L2_EVICTED); + hdr->b_flags &= ~ARC_L2_EVICTED; if (l2arc_noprefetch && (hdr->b_flags & ARC_PREFETCH)) - hdr->b_flags |= ARC_DONT_L2CACHE; + hdr->b_flags &= ~ARC_L2CACHE; /* byteswap if necessary */ callback_list = hdr->b_acb; ASSERT(callback_list != NULL); - if (BP_SHOULD_BYTESWAP(zio->io_bp) && callback_list->acb_byteswap) - callback_list->acb_byteswap(buf->b_data, hdr->b_size); + if (BP_SHOULD_BYTESWAP(zio->io_bp)) { + arc_byteswap_func_t *func = BP_GET_LEVEL(zio->io_bp) > 0 ? + byteswap_uint64_array : + dmu_ot[BP_GET_TYPE(zio->io_bp)].ot_byteswap; + func(buf->b_data, hdr->b_size); + } arc_cksum_compute(buf, B_FALSE); @@ -2318,9 +2357,6 @@ arc_read_done(zio_t *zio) if (HDR_IN_HASH_TABLE(hdr)) buf_hash_remove(hdr); freeable = refcount_is_zero(&hdr->b_refcnt); - /* convert checksum errors into IO errors */ - if (zio->io_error == ECKSUM) - zio->io_error = EIO; } /* @@ -2386,11 +2422,35 @@ arc_read_done(zio_t *zio) * * arc_read_done() will invoke all the requested "done" functions * for readers of this block. + * + * Normal callers should use arc_read and pass the arc buffer and offset + * for the bp. But if you know you don't need locking, you can use + * arc_read_bp. */ int -arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_byteswap_func_t *swap, - arc_done_func_t *done, void *private, int priority, int flags, - uint32_t *arc_flags, zbookmark_t *zb) +arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf, + arc_done_func_t *done, void *private, int priority, int zio_flags, + uint32_t *arc_flags, const zbookmark_t *zb) +{ + int err; + arc_buf_hdr_t *hdr = pbuf->b_hdr; + + ASSERT(!refcount_is_zero(&pbuf->b_hdr->b_refcnt)); + ASSERT3U((char *)bp - (char *)pbuf->b_data, <, pbuf->b_hdr->b_size); + rw_enter(&pbuf->b_lock, RW_READER); + + err = arc_read_nolock(pio, spa, bp, done, private, priority, + zio_flags, arc_flags, zb); + + ASSERT3P(hdr, ==, pbuf->b_hdr); + rw_exit(&pbuf->b_lock); + return (err); +} + +int +arc_read_nolock(zio_t *pio, spa_t *spa, blkptr_t *bp, + arc_done_func_t *done, void *private, int priority, int zio_flags, + uint32_t *arc_flags, const zbookmark_t *zb) { arc_buf_hdr_t *hdr; arc_buf_t *buf; @@ -2419,10 +2479,9 @@ top: KM_SLEEP); acb->acb_done = done; acb->acb_private = private; - acb->acb_byteswap = swap; if (pio != NULL) acb->acb_zio_dummy = zio_null(pio, - spa, NULL, NULL, flags); + spa, NULL, NULL, zio_flags); ASSERT(acb->acb_done != NULL); acb->acb_next = hdr->b_acb; @@ -2459,6 +2518,8 @@ top: } DTRACE_PROBE1(arc__hit, arc_buf_hdr_t *, hdr); arc_access(hdr, hash_lock); + if (*arc_flags & ARC_L2CACHE) + hdr->b_flags |= ARC_L2CACHE; mutex_exit(hash_lock); ARCSTAT_BUMP(arcstat_hits); ARCSTAT_CONDSTAT(!(hdr->b_flags & ARC_PREFETCH), @@ -2470,6 +2531,8 @@ top: } else { uint64_t size = BP_GET_LSIZE(bp); arc_callback_t *acb; + vdev_t *vd = NULL; + daddr_t addr; if (hdr == NULL) { /* this block is not in the cache */ @@ -2496,6 +2559,8 @@ top: private); hdr->b_flags |= ARC_PREFETCH; } + if (*arc_flags & ARC_L2CACHE) + hdr->b_flags |= ARC_L2CACHE; if (BP_GET_LEVEL(bp) > 0) hdr->b_flags |= ARC_INDIRECT; } else { @@ -2510,6 +2575,8 @@ top: hdr->b_flags |= ARC_PREFETCH; else add_reference(hdr, hash_lock, private); + if (*arc_flags & ARC_L2CACHE) + hdr->b_flags |= ARC_L2CACHE; buf = kmem_cache_alloc(buf_cache, KM_PUSHPAGE); buf->b_hdr = hdr; buf->b_data = NULL; @@ -2526,7 +2593,6 @@ top: acb = kmem_zalloc(sizeof (arc_callback_t), KM_SLEEP); acb->acb_done = done; acb->acb_private = private; - acb->acb_byteswap = swap; ASSERT(hdr->b_acb == NULL); hdr->b_acb = acb; @@ -2543,6 +2609,19 @@ top: if (GHOST_STATE(hdr->b_state)) arc_access(hdr, hash_lock); + if (HDR_L2CACHE(hdr) && hdr->b_l2hdr != NULL && + (vd = hdr->b_l2hdr->b_dev->l2ad_vdev) != NULL) { + addr = hdr->b_l2hdr->b_daddr; + /* + * Lock out device removal. + */ + if (vdev_is_dead(vd) || + !spa_config_tryenter(spa, SCL_L2ARC, vd, RW_READER)) + vd = NULL; + } + + mutex_exit(hash_lock); + ASSERT3U(hdr->b_size, ==, size); DTRACE_PROBE3(arc__miss, blkptr_t *, bp, uint64_t, size, zbookmark_t *, zb); @@ -2551,59 +2630,65 @@ top: demand, prefetch, hdr->b_type != ARC_BUFC_METADATA, data, metadata, misses); - if (l2arc_ndev != 0) { + if (vd != NULL) { /* * Read from the L2ARC if the following are true: - * 1. This buffer has L2ARC metadata. - * 2. This buffer isn't currently writing to the L2ARC. + * 1. The L2ARC vdev was previously cached. + * 2. This buffer still has L2ARC metadata. + * 3. This buffer isn't currently writing to the L2ARC. + * 4. The L2ARC entry wasn't evicted, which may + * also have invalidated the vdev. */ - if (hdr->b_l2hdr != NULL && !HDR_L2_WRITING(hdr)) { - vdev_t *vd = hdr->b_l2hdr->b_dev->l2ad_vdev; - daddr_t addr = hdr->b_l2hdr->b_daddr; + if (hdr->b_l2hdr != NULL && + !HDR_L2_WRITING(hdr) && !HDR_L2_EVICTED(hdr)) { l2arc_read_callback_t *cb; DTRACE_PROBE1(l2arc__hit, arc_buf_hdr_t *, hdr); ARCSTAT_BUMP(arcstat_l2_hits); - hdr->b_flags |= ARC_L2_READING; - mutex_exit(hash_lock); - cb = kmem_zalloc(sizeof (l2arc_read_callback_t), KM_SLEEP); cb->l2rcb_buf = buf; cb->l2rcb_spa = spa; cb->l2rcb_bp = *bp; cb->l2rcb_zb = *zb; - cb->l2rcb_flags = flags; + cb->l2rcb_flags = zio_flags; /* - * l2arc read. + * l2arc read. The SCL_L2ARC lock will be + * released by l2arc_read_done(). */ rzio = zio_read_phys(pio, vd, addr, size, buf->b_data, ZIO_CHECKSUM_OFF, - l2arc_read_done, cb, priority, - flags | ZIO_FLAG_DONT_CACHE, B_FALSE); + l2arc_read_done, cb, priority, zio_flags | + ZIO_FLAG_DONT_CACHE | ZIO_FLAG_CANFAIL | + ZIO_FLAG_DONT_PROPAGATE | + ZIO_FLAG_DONT_RETRY, B_FALSE); DTRACE_PROBE2(l2arc__read, vdev_t *, vd, zio_t *, rzio); - if (*arc_flags & ARC_WAIT) - return (zio_wait(rzio)); + if (*arc_flags & ARC_NOWAIT) { + zio_nowait(rzio); + return (0); + } - ASSERT(*arc_flags & ARC_NOWAIT); - zio_nowait(rzio); - return (0); + ASSERT(*arc_flags & ARC_WAIT); + if (zio_wait(rzio) == 0) + return (0); + + /* l2arc read error; goto zio_read() */ } else { DTRACE_PROBE1(l2arc__miss, arc_buf_hdr_t *, hdr); ARCSTAT_BUMP(arcstat_l2_misses); if (HDR_L2_WRITING(hdr)) ARCSTAT_BUMP(arcstat_l2_rw_clash); + spa_config_exit(spa, SCL_L2ARC, vd); } } - mutex_exit(hash_lock); rzio = zio_read(pio, spa, bp, buf->b_data, size, - arc_read_done, buf, priority, flags, zb); + arc_read_done, buf, priority, zio_flags, zb); if (*arc_flags & ARC_WAIT) return (zio_wait(rzio)); @@ -2670,46 +2755,29 @@ arc_buf_evict(arc_buf_t *buf) kmutex_t *hash_lock; arc_buf_t **bufp; - mutex_enter(&arc_eviction_mtx); + rw_enter(&buf->b_lock, RW_WRITER); hdr = buf->b_hdr; if (hdr == NULL) { /* * We are in arc_do_user_evicts(). */ ASSERT(buf->b_data == NULL); - mutex_exit(&arc_eviction_mtx); + rw_exit(&buf->b_lock); return (0); + } else if (buf->b_data == NULL) { + arc_buf_t copy = *buf; /* structure assignment */ + /* + * We are on the eviction list; process this buffer now + * but let arc_do_user_evicts() do the reaping. + */ + buf->b_efunc = NULL; + rw_exit(&buf->b_lock); + VERIFY(copy.b_efunc(©) == 0); + return (1); } hash_lock = HDR_LOCK(hdr); - mutex_exit(&arc_eviction_mtx); - mutex_enter(hash_lock); - if (buf->b_data == NULL) { - /* - * We are on the eviction list. - */ - mutex_exit(hash_lock); - mutex_enter(&arc_eviction_mtx); - if (buf->b_hdr == NULL) { - /* - * We are already in arc_do_user_evicts(). - */ - mutex_exit(&arc_eviction_mtx); - return (0); - } else { - arc_buf_t copy = *buf; /* structure assignment */ - /* - * Process this buffer now - * but let arc_do_user_evicts() do the reaping. - */ - buf->b_efunc = NULL; - mutex_exit(&arc_eviction_mtx); - VERIFY(copy.b_efunc(©) == 0); - return (1); - } - } - ASSERT(buf->b_hdr == hdr); ASSERT3U(refcount_count(&hdr->b_refcnt), <, hdr->b_datacnt); ASSERT(hdr->b_state == arc_mru || hdr->b_state == arc_mfu); @@ -2746,6 +2814,7 @@ arc_buf_evict(arc_buf_t *buf) mutex_exit(&old_state->arcs_mtx); } mutex_exit(hash_lock); + rw_exit(&buf->b_lock); VERIFY(buf->b_efunc(buf) == 0); buf->b_efunc = NULL; @@ -2759,18 +2828,22 @@ arc_buf_evict(arc_buf_t *buf) * Release this buffer from the cache. This must be done * after a read and prior to modifying the buffer contents. * If the buffer has more than one reference, we must make - * make a new hdr for the buffer. + * a new hdr for the buffer. */ void arc_release(arc_buf_t *buf, void *tag) { - arc_buf_hdr_t *hdr = buf->b_hdr; - kmutex_t *hash_lock = HDR_LOCK(hdr); - l2arc_buf_hdr_t *l2hdr = NULL; + arc_buf_hdr_t *hdr; + kmutex_t *hash_lock; + l2arc_buf_hdr_t *l2hdr; uint64_t buf_size; + rw_enter(&buf->b_lock, RW_WRITER); + hdr = buf->b_hdr; + /* this buffer is not on any list */ ASSERT(refcount_count(&hdr->b_refcnt) > 0); + ASSERT(!(hdr->b_flags & ARC_STORED)); if (hdr->b_state == arc_anon) { /* this buffer is already released */ @@ -2778,15 +2851,24 @@ arc_release(arc_buf_t *buf, void *tag) ASSERT(BUF_EMPTY(hdr)); ASSERT(buf->b_efunc == NULL); arc_buf_thaw(buf); + rw_exit(&buf->b_lock); return; } + hash_lock = HDR_LOCK(hdr); mutex_enter(hash_lock); + l2hdr = hdr->b_l2hdr; + if (l2hdr) { + mutex_enter(&l2arc_buflist_mtx); + hdr->b_l2hdr = NULL; + buf_size = hdr->b_size; + } + /* * Do we have more than one buf? */ - if (hdr->b_buf != buf || buf->b_next != NULL) { + if (hdr->b_datacnt > 1) { arc_buf_hdr_t *nhdr; arc_buf_t **bufp; uint64_t blksz = hdr->b_size; @@ -2794,7 +2876,7 @@ arc_release(arc_buf_t *buf, void *tag) arc_buf_contents_t type = hdr->b_type; uint32_t flags = hdr->b_flags; - ASSERT(hdr->b_datacnt > 1); + ASSERT(hdr->b_buf != buf || buf->b_next != NULL); /* * Pull the data off of this buf and attach it to * a new anonymous buf. @@ -2814,12 +2896,6 @@ arc_release(arc_buf_t *buf, void *tag) atomic_add_64(size, -hdr->b_size); } hdr->b_datacnt -= 1; - if (hdr->b_l2hdr != NULL) { - mutex_enter(&l2arc_buflist_mtx); - l2hdr = hdr->b_l2hdr; - hdr->b_l2hdr = NULL; - buf_size = hdr->b_size; - } arc_cksum_verify(buf); mutex_exit(hash_lock); @@ -2837,19 +2913,15 @@ arc_release(arc_buf_t *buf, void *tag) nhdr->b_freeze_cksum = NULL; (void) refcount_add(&nhdr->b_refcnt, tag); buf->b_hdr = nhdr; + rw_exit(&buf->b_lock); atomic_add_64(&arc_anon->arcs_size, blksz); } else { + rw_exit(&buf->b_lock); ASSERT(refcount_count(&hdr->b_refcnt) == 1); ASSERT(!list_link_active(&hdr->b_arc_node)); ASSERT(!HDR_IO_IN_PROGRESS(hdr)); arc_change_state(arc_anon, hdr, hash_lock); hdr->b_arc_access = 0; - if (hdr->b_l2hdr != NULL) { - mutex_enter(&l2arc_buflist_mtx); - l2hdr = hdr->b_l2hdr; - hdr->b_l2hdr = NULL; - buf_size = hdr->b_size; - } mutex_exit(hash_lock); bzero(&hdr->b_dva, sizeof (dva_t)); @@ -2864,28 +2936,42 @@ arc_release(arc_buf_t *buf, void *tag) list_remove(l2hdr->b_dev->l2ad_buflist, hdr); kmem_free(l2hdr, sizeof (l2arc_buf_hdr_t)); ARCSTAT_INCR(arcstat_l2_size, -buf_size); - } - if (MUTEX_HELD(&l2arc_buflist_mtx)) mutex_exit(&l2arc_buflist_mtx); + } } int arc_released(arc_buf_t *buf) { - return (buf->b_data != NULL && buf->b_hdr->b_state == arc_anon); + int released; + + rw_enter(&buf->b_lock, RW_READER); + released = (buf->b_data != NULL && buf->b_hdr->b_state == arc_anon); + rw_exit(&buf->b_lock); + return (released); } int arc_has_callback(arc_buf_t *buf) { - return (buf->b_efunc != NULL); + int callback; + + rw_enter(&buf->b_lock, RW_READER); + callback = (buf->b_efunc != NULL); + rw_exit(&buf->b_lock); + return (callback); } #ifdef ZFS_DEBUG int arc_referenced(arc_buf_t *buf) { - return (refcount_count(&buf->b_hdr->b_refcnt)); + int referenced; + + rw_enter(&buf->b_lock, RW_READER); + referenced = (refcount_count(&buf->b_hdr->b_refcnt)); + rw_exit(&buf->b_lock); + return (referenced); } #endif @@ -2896,23 +2982,16 @@ arc_write_ready(zio_t *zio) arc_buf_t *buf = callback->awcb_buf; arc_buf_hdr_t *hdr = buf->b_hdr; - if (zio->io_error == 0 && callback->awcb_ready) { - ASSERT(!refcount_is_zero(&buf->b_hdr->b_refcnt)); - callback->awcb_ready(zio, buf, callback->awcb_private); - } + ASSERT(!refcount_is_zero(&buf->b_hdr->b_refcnt)); + callback->awcb_ready(zio, buf, callback->awcb_private); + /* * If the IO is already in progress, then this is a re-write - * attempt, so we need to thaw and re-compute the cksum. It is - * the responsibility of the callback to handle the freeing - * and accounting for any re-write attempt. If we don't have a - * callback registered then simply free the block here. + * attempt, so we need to thaw and re-compute the cksum. + * It is the responsibility of the callback to handle the + * accounting for any re-write attempt. */ if (HDR_IO_IN_PROGRESS(hdr)) { - if (!BP_IS_HOLE(&zio->io_bp_orig) && - callback->awcb_ready == NULL) { - zio_nowait(zio_free(zio, zio->io_spa, zio->io_txg, - &zio->io_bp_orig, NULL, NULL)); - } mutex_enter(&hdr->b_freeze_lock); if (hdr->b_freeze_cksum != NULL) { kmem_free(hdr->b_freeze_cksum, sizeof (zio_cksum_t)); @@ -2933,9 +3012,6 @@ arc_write_done(zio_t *zio) hdr->b_acb = NULL; - /* this buffer is on no lists and is not in the hash table */ - ASSERT3P(hdr->b_state, ==, arc_anon); - hdr->b_dva = *BP_IDENTITY(zio->io_bp); hdr->b_birth = zio->io_bp->blk_birth; hdr->b_cksum0 = zio->io_bp->blk_cksum.zc_word[0]; @@ -2958,6 +3034,7 @@ arc_write_done(zio_t *zio) * sync-to-convergence, because we remove * buffers from the hash table when we arc_free(). */ + ASSERT(zio->io_flags & ZIO_FLAG_IO_REWRITE); ASSERT(DVA_EQUAL(BP_IDENTITY(&zio->io_bp_orig), BP_IDENTITY(zio->io_bp))); ASSERT3U(zio->io_bp_orig.blk_birth, ==, @@ -2971,7 +3048,9 @@ arc_write_done(zio_t *zio) ASSERT3P(exists, ==, NULL); } hdr->b_flags &= ~ARC_IO_IN_PROGRESS; - arc_access(hdr, hash_lock); + /* if it's not anon, we are doing a scrub */ + if (hdr->b_state == arc_anon) + arc_access(hdr, hash_lock); mutex_exit(hash_lock); } else if (callback->awcb_done == NULL) { int destroy_hdr; @@ -2988,6 +3067,7 @@ arc_write_done(zio_t *zio) } else { hdr->b_flags &= ~ARC_IO_IN_PROGRESS; } + hdr->b_flags &= ~ARC_STORED; if (callback->awcb_done) { ASSERT(!refcount_is_zero(&hdr->b_refcnt)); @@ -2997,30 +3077,74 @@ arc_write_done(zio_t *zio) kmem_free(callback, sizeof (arc_write_callback_t)); } +void +write_policy(spa_t *spa, const writeprops_t *wp, zio_prop_t *zp) +{ + boolean_t ismd = (wp->wp_level > 0 || dmu_ot[wp->wp_type].ot_metadata); + + /* Determine checksum setting */ + if (ismd) { + /* + * Metadata always gets checksummed. If the data + * checksum is multi-bit correctable, and it's not a + * ZBT-style checksum, then it's suitable for metadata + * as well. Otherwise, the metadata checksum defaults + * to fletcher4. + */ + if (zio_checksum_table[wp->wp_oschecksum].ci_correctable && + !zio_checksum_table[wp->wp_oschecksum].ci_zbt) + zp->zp_checksum = wp->wp_oschecksum; + else + zp->zp_checksum = ZIO_CHECKSUM_FLETCHER_4; + } else { + zp->zp_checksum = zio_checksum_select(wp->wp_dnchecksum, + wp->wp_oschecksum); + } + + /* Determine compression setting */ + if (ismd) { + /* + * XXX -- we should design a compression algorithm + * that specializes in arrays of bps. + */ + zp->zp_compress = zfs_mdcomp_disable ? ZIO_COMPRESS_EMPTY : + ZIO_COMPRESS_LZJB; + } else { + zp->zp_compress = zio_compress_select(wp->wp_dncompress, + wp->wp_oscompress); + } + + zp->zp_type = wp->wp_type; + zp->zp_level = wp->wp_level; + zp->zp_ndvas = MIN(wp->wp_copies + ismd, spa_max_replication(spa)); +} + zio_t * -arc_write(zio_t *pio, spa_t *spa, int checksum, int compress, int ncopies, - uint64_t txg, blkptr_t *bp, arc_buf_t *buf, +arc_write(zio_t *pio, spa_t *spa, const writeprops_t *wp, + boolean_t l2arc, uint64_t txg, blkptr_t *bp, arc_buf_t *buf, arc_done_func_t *ready, arc_done_func_t *done, void *private, int priority, - int flags, zbookmark_t *zb) + int zio_flags, const zbookmark_t *zb) { arc_buf_hdr_t *hdr = buf->b_hdr; arc_write_callback_t *callback; - zio_t *zio; + zio_t *zio; + zio_prop_t zp; - /* this is a private buffer - no locking required */ - ASSERT3P(hdr->b_state, ==, arc_anon); - ASSERT(BUF_EMPTY(hdr)); + ASSERT(ready != NULL); ASSERT(!HDR_IO_ERROR(hdr)); ASSERT((hdr->b_flags & ARC_IO_IN_PROGRESS) == 0); ASSERT(hdr->b_acb == 0); + if (l2arc) + hdr->b_flags |= ARC_L2CACHE; callback = kmem_zalloc(sizeof (arc_write_callback_t), KM_SLEEP); callback->awcb_ready = ready; callback->awcb_done = done; callback->awcb_private = private; callback->awcb_buf = buf; - zio = zio_write(pio, spa, checksum, compress, ncopies, txg, bp, - buf->b_data, hdr->b_size, arc_write_ready, arc_write_done, callback, - priority, flags, zb); + + write_policy(spa, wp, &zp); + zio = zio_write(pio, spa, txg, bp, buf->b_data, hdr->b_size, &zp, + arc_write_ready, arc_write_done, callback, priority, zio_flags, zb); return (zio); } @@ -3045,7 +3169,9 @@ arc_free(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, * nonzero, it should match what we have in the cache. */ ASSERT(bp->blk_cksum.zc_word[0] == 0 || - ab->b_cksum0 == bp->blk_cksum.zc_word[0]); + bp->blk_cksum.zc_word[0] == ab->b_cksum0 || + bp->blk_fill == BLK_FILL_ALREADY_FREED); + if (ab->b_state != arc_anon) arc_change_state(arc_anon, ab, hash_lock); if (HDR_IO_IN_PROGRESS(ab)) { @@ -3086,7 +3212,7 @@ arc_free(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, } } - zio = zio_free(pio, spa, txg, bp, done, private); + zio = zio_free(pio, spa, txg, bp, done, private, ZIO_FLAG_MUSTSUCCEED); if (arc_flags & ARC_WAIT) return (zio_wait(zio)); @@ -3320,12 +3446,13 @@ arc_init(void) TS_RUN, minclsyspri); arc_dead = FALSE; + arc_warm = B_FALSE; if (zfs_write_limit_max == 0) - zfs_write_limit_max = physmem * PAGESIZE >> - zfs_write_limit_shift; + zfs_write_limit_max = ptob(physmem) >> zfs_write_limit_shift; else zfs_write_limit_shift = 0; + mutex_init(&zfs_write_limit_lock, NULL, MUTEX_DEFAULT, NULL); } void @@ -3365,6 +3492,8 @@ arc_fini(void) mutex_destroy(&arc_mfu->arcs_mtx); mutex_destroy(&arc_mfu_ghost->arcs_mtx); + mutex_destroy(&zfs_write_limit_lock); + buf_fini(); } @@ -3460,21 +3589,33 @@ arc_fini(void) * the potential for the L2ARC to churn if it attempts to cache content too * quickly, such as during backups of the entire pool. * - * 5. Writes to the L2ARC devices are grouped and sent in-sequence, so that + * 5. After system boot and before the ARC has filled main memory, there are + * no evictions from the ARC and so the tails of the ARC_mfu and ARC_mru + * lists can remain mostly static. Instead of searching from tail of these + * lists as pictured, the l2arc_feed_thread() will search from the list heads + * for eligible buffers, greatly increasing its chance of finding them. + * + * The L2ARC device write speed is also boosted during this time so that + * the L2ARC warms up faster. Since there have been no ARC evictions yet, + * there are no L2ARC reads, and no fear of degrading read performance + * through increased writes. + * + * 6. Writes to the L2ARC devices are grouped and sent in-sequence, so that * the vdev queue can aggregate them into larger and fewer writes. Each * device is written to in a rotor fashion, sweeping writes through * available space then repeating. * - * 6. The L2ARC does not store dirty content. It never needs to flush + * 7. The L2ARC does not store dirty content. It never needs to flush * write buffers back to disk based storage. * - * 7. If an ARC buffer is written (and dirtied) which also exists in the + * 8. If an ARC buffer is written (and dirtied) which also exists in the * L2ARC, the now stale L2ARC buffer is immediately dropped. * * The performance of the L2ARC can be tweaked by a number of tunables, which * may be necessary for different workloads: * * l2arc_write_max max write bytes per interval + * l2arc_write_boost extra write bytes during device warmup * l2arc_noprefetch skip caching prefetched buffers * l2arc_headroom number of max device writes to precache * l2arc_feed_secs seconds between L2ARC writing @@ -3499,26 +3640,89 @@ l2arc_hdr_stat_remove(void) /* * Cycle through L2ARC devices. This is how L2ARC load balances. - * This is called with l2arc_dev_mtx held, which also locks out spa removal. + * If a device is returned, this also returns holding the spa config lock. */ static l2arc_dev_t * l2arc_dev_get_next(void) { - l2arc_dev_t *next; + l2arc_dev_t *first, *next = NULL; - if (l2arc_dev_last == NULL) { - next = list_head(l2arc_dev_list); - } else { - next = list_next(l2arc_dev_list, l2arc_dev_last); - if (next == NULL) + /* + * Lock out the removal of spas (spa_namespace_lock), then removal + * of cache devices (l2arc_dev_mtx). Once a device has been selected, + * both locks will be dropped and a spa config lock held instead. + */ + mutex_enter(&spa_namespace_lock); + mutex_enter(&l2arc_dev_mtx); + + /* if there are no vdevs, there is nothing to do */ + if (l2arc_ndev == 0) + goto out; + + first = NULL; + next = l2arc_dev_last; + do { + /* loop around the list looking for a non-faulted vdev */ + if (next == NULL) { next = list_head(l2arc_dev_list); - } + } else { + next = list_next(l2arc_dev_list, next); + if (next == NULL) + next = list_head(l2arc_dev_list); + } + + /* if we have come back to the start, bail out */ + if (first == NULL) + first = next; + else if (next == first) + break; + + } while (vdev_is_dead(next->l2ad_vdev)); + + /* if we were unable to find any usable vdevs, return NULL */ + if (vdev_is_dead(next->l2ad_vdev)) + next = NULL; l2arc_dev_last = next; +out: + mutex_exit(&l2arc_dev_mtx); + + /* + * Grab the config lock to prevent the 'next' device from being + * removed while we are writing to it. + */ + if (next != NULL) + spa_config_enter(next->l2ad_spa, SCL_L2ARC, next, RW_READER); + mutex_exit(&spa_namespace_lock); + return (next); } +/* + * Free buffers that were tagged for destruction. + */ +static void +l2arc_do_free_on_write() +{ + list_t *buflist; + l2arc_data_free_t *df, *df_prev; + + mutex_enter(&l2arc_free_on_write_mtx); + buflist = l2arc_free_on_write; + + for (df = list_tail(buflist); df; df = df_prev) { + df_prev = list_prev(buflist, df); + ASSERT(df->l2df_data != NULL); + ASSERT(df->l2df_func != NULL); + df->l2df_func(df->l2df_data, df->l2df_size); + list_remove(buflist, df); + kmem_free(df, sizeof (l2arc_data_free_t)); + } + + mutex_exit(&l2arc_free_on_write_mtx); +} + /* * A write to a cache device has completed. Update all headers to allow * reads from these buffers to begin. @@ -3529,8 +3733,8 @@ l2arc_write_done(zio_t *zio) l2arc_write_callback_t *cb; l2arc_dev_t *dev; list_t *buflist; - l2arc_data_free_t *df, *df_prev; arc_buf_hdr_t *head, *ab, *ab_prev; + l2arc_buf_hdr_t *abl2; kmutex_t *hash_lock; cb = zio->io_private; @@ -3568,9 +3772,13 @@ l2arc_write_done(zio_t *zio) if (zio->io_error != 0) { /* - * Error - invalidate L2ARC entry. + * Error - drop L2ARC entry. */ + list_remove(buflist, ab); + abl2 = ab->b_l2hdr; ab->b_l2hdr = NULL; + kmem_free(abl2, sizeof (l2arc_buf_hdr_t)); + ARCSTAT_INCR(arcstat_l2_size, -ab->b_size); } /* @@ -3586,20 +3794,7 @@ l2arc_write_done(zio_t *zio) kmem_cache_free(hdr_cache, head); mutex_exit(&l2arc_buflist_mtx); - /* - * Free buffers that were tagged for destruction. - */ - mutex_enter(&l2arc_free_on_write_mtx); - buflist = l2arc_free_on_write; - for (df = list_tail(buflist); df; df = df_prev) { - df_prev = list_prev(buflist, df); - ASSERT(df->l2df_data != NULL); - ASSERT(df->l2df_func != NULL); - df->l2df_func(df->l2df_data, df->l2df_size); - list_remove(buflist, df); - kmem_free(df, sizeof (l2arc_data_free_t)); - } - mutex_exit(&l2arc_free_on_write_mtx); + l2arc_do_free_on_write(); kmem_free(cb, sizeof (l2arc_write_callback_t)); } @@ -3614,9 +3809,13 @@ l2arc_read_done(zio_t *zio) l2arc_read_callback_t *cb; arc_buf_hdr_t *hdr; arc_buf_t *buf; - zio_t *rzio; kmutex_t *hash_lock; - int equal, err = 0; + int equal; + + ASSERT(zio->io_vd != NULL); + ASSERT(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE); + + spa_config_exit(zio->io_spa, SCL_L2ARC, zio->io_vd); cb = zio->io_private; ASSERT(cb != NULL); @@ -3635,6 +3834,8 @@ l2arc_read_done(zio_t *zio) if (equal && zio->io_error == 0 && !HDR_L2_EVICTED(hdr)) { mutex_exit(hash_lock); zio->io_private = buf; + zio->io_bp_copy = cb->l2rcb_bp; /* XXX fix in L2ARC 2.0 */ + zio->io_bp = &zio->io_bp_copy; /* XXX fix in L2ARC 2.0 */ arc_read_done(zio); } else { mutex_exit(hash_lock); @@ -3642,29 +3843,24 @@ l2arc_read_done(zio_t *zio) * Buffer didn't survive caching. Increment stats and * reissue to the original storage device. */ - if (zio->io_error != 0) + if (zio->io_error != 0) { ARCSTAT_BUMP(arcstat_l2_io_error); + } else { + zio->io_error = EIO; + } if (!equal) ARCSTAT_BUMP(arcstat_l2_cksum_bad); - zio->io_flags &= ~ZIO_FLAG_DONT_CACHE; - rzio = zio_read(NULL, cb->l2rcb_spa, &cb->l2rcb_bp, - buf->b_data, zio->io_size, arc_read_done, buf, - zio->io_priority, cb->l2rcb_flags, &cb->l2rcb_zb); - /* - * Since this is a seperate thread, we can wait on this - * I/O whether there is an io_waiter or not. + * If there's no waiter, issue an async i/o to the primary + * storage now. If there *is* a waiter, the caller must + * issue the i/o in a context where it's OK to block. */ - err = zio_wait(rzio); - - /* - * Let the resent I/O call arc_read_done() instead. - * io_error is set to the reissued I/O error status. - */ - zio->io_done = NULL; - zio->io_waiter = NULL; - zio->io_error = err; + if (zio->io_waiter == NULL) + zio_nowait(zio_read(zio->io_parent, + cb->l2rcb_spa, &cb->l2rcb_bp, + buf->b_data, zio->io_size, arc_read_done, buf, + zio->io_priority, cb->l2rcb_flags, &cb->l2rcb_zb)); } kmem_free(cb, sizeof (l2arc_read_callback_t)); @@ -3726,8 +3922,6 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all) kmutex_t *hash_lock; uint64_t taddr; - ASSERT(MUTEX_HELD(&l2arc_dev_mtx)); - buflist = dev->l2ad_buflist; if (buflist == NULL) @@ -3741,7 +3935,7 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all) return; } - if (dev->l2ad_hand >= (dev->l2ad_end - (2 * dev->l2ad_write))) { + if (dev->l2ad_hand >= (dev->l2ad_end - (2 * distance))) { /* * When nearing the end of the device, evict to the end * before the device write hand jumps to the start. @@ -3809,6 +4003,16 @@ top: arc_change_state(arc_anon, ab, hash_lock); arc_hdr_destroy(ab); } else { + /* + * Invalidate issued or about to be issued + * reads, since we may be about to write + * over this location. + */ + if (HDR_L2_READING(ab)) { + ARCSTAT_BUMP(arcstat_l2_evict_reading); + ab->b_flags |= ARC_L2_EVICTED; + } + /* * Tell ARC this no longer exists in L2ARC. */ @@ -3825,16 +4029,6 @@ top: * failed write. */ ab->b_flags &= ~ARC_L2_WRITING; - - /* - * Invalidate issued or about to be issued - * reads, since we may be about to write - * over this location. - */ - if (HDR_L2_READING(ab)) { - ARCSTAT_BUMP(arcstat_l2_evict_reading); - ab->b_flags |= ARC_L2_EVICTED; - } } mutex_exit(hash_lock); } @@ -3851,21 +4045,18 @@ top: * for reading until they have completed writing. */ static void -l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev) +l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) { arc_buf_hdr_t *ab, *ab_prev, *head; l2arc_buf_hdr_t *hdrl2; list_t *list; - uint64_t passed_sz, write_sz, buf_sz; - uint64_t target_sz = dev->l2ad_write; - uint64_t headroom = dev->l2ad_write * l2arc_headroom; + uint64_t passed_sz, write_sz, buf_sz, headroom; void *buf_data; kmutex_t *hash_lock, *list_lock; boolean_t have_lock, full; l2arc_write_callback_t *cb; zio_t *pio, *wzio; - ASSERT(MUTEX_HELD(&l2arc_dev_mtx)); ASSERT(dev->l2ad_vdev != NULL); pio = NULL; @@ -3882,8 +4073,23 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev) list = l2arc_list_locked(try, &list_lock); passed_sz = 0; - for (ab = list_tail(list); ab; ab = ab_prev) { - ab_prev = list_prev(list, ab); + /* + * L2ARC fast warmup. + * + * Until the ARC is warm and starts to evict, read from the + * head of the ARC lists rather than the tail. + */ + headroom = target_sz * l2arc_headroom; + if (arc_warm == B_FALSE) + ab = list_head(list); + else + ab = list_tail(list); + + for (; ab; ab = ab_prev) { + if (arc_warm == B_FALSE) + ab_prev = list_next(list, ab); + else + ab_prev = list_prev(list, ab); hash_lock = HDR_LOCK(ab); have_lock = MUTEX_HELD(hash_lock); @@ -3916,7 +4122,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev) continue; } - if (HDR_IO_IN_PROGRESS(ab) || HDR_DONT_L2CACHE(ab)) { + if (HDR_IO_IN_PROGRESS(ab) || !HDR_L2CACHE(ab)) { mutex_exit(hash_lock); continue; } @@ -3980,6 +4186,11 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev) zio_t *, wzio); (void) zio_nowait(wzio); + /* + * Keep the clock hand suitably device-aligned. + */ + buf_sz = vdev_psize_to_asize(dev->l2ad_vdev, buf_sz); + write_sz += buf_sz; dev->l2ad_hand += buf_sz; } @@ -4006,7 +4217,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev) * Bump device hand to the device start if it is approaching the end. * l2arc_evict() will already have evicted ahead for this case. */ - if (dev->l2ad_hand >= (dev->l2ad_end - dev->l2ad_write)) { + if (dev->l2ad_hand >= (dev->l2ad_end - target_sz)) { spa_l2cache_space_update(dev->l2ad_vdev, 0, dev->l2ad_end - dev->l2ad_hand); dev->l2ad_hand = dev->l2ad_start; @@ -4027,8 +4238,7 @@ l2arc_feed_thread(void) callb_cpr_t cpr; l2arc_dev_t *dev; spa_t *spa; - int interval; - boolean_t startup = B_TRUE; + uint64_t size; CALLB_CPR_INIT(&cpr, &l2arc_feed_thr_lock, callb_generic_cpr, FTAG); @@ -4036,61 +4246,64 @@ l2arc_feed_thread(void) while (l2arc_thread_exit == 0) { /* - * Initially pause for L2ARC_FEED_DELAY seconds as a grace - * interval during boot, followed by l2arc_feed_secs seconds - * thereafter. + * Pause for l2arc_feed_secs seconds between writes. */ CALLB_CPR_SAFE_BEGIN(&cpr); - if (startup) { - interval = L2ARC_FEED_DELAY; - startup = B_FALSE; - } else { - interval = l2arc_feed_secs; - } (void) cv_timedwait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock, - lbolt + (hz * interval)); + lbolt + (hz * l2arc_feed_secs)); CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock); /* - * Do nothing until L2ARC devices exist. + * Quick check for L2ARC devices. */ mutex_enter(&l2arc_dev_mtx); if (l2arc_ndev == 0) { mutex_exit(&l2arc_dev_mtx); continue; } + mutex_exit(&l2arc_dev_mtx); + + /* + * This selects the next l2arc device to write to, and in + * doing so the next spa to feed from: dev->l2ad_spa. This + * will return NULL if there are now no l2arc devices or if + * they are all faulted. + * + * If a device is returned, its spa's config lock is also + * held to prevent device removal. l2arc_dev_get_next() + * will grab and release l2arc_dev_mtx. + */ + if ((dev = l2arc_dev_get_next()) == NULL) + continue; + + spa = dev->l2ad_spa; + ASSERT(spa != NULL); /* * Avoid contributing to memory pressure. */ if (arc_reclaim_needed()) { ARCSTAT_BUMP(arcstat_l2_abort_lowmem); - mutex_exit(&l2arc_dev_mtx); + spa_config_exit(spa, SCL_L2ARC, dev); continue; } - /* - * This selects the next l2arc device to write to, and in - * doing so the next spa to feed from: dev->l2ad_spa. - */ - if ((dev = l2arc_dev_get_next()) == NULL) { - mutex_exit(&l2arc_dev_mtx); - continue; - } - spa = dev->l2ad_spa; - ASSERT(spa != NULL); ARCSTAT_BUMP(arcstat_l2_feeds); + size = dev->l2ad_write; + if (arc_warm == B_FALSE) + size += dev->l2ad_boost; + /* * Evict L2ARC buffers that will be overwritten. */ - l2arc_evict(dev, dev->l2ad_write, B_FALSE); + l2arc_evict(dev, size, B_FALSE); /* * Write ARC buffers. */ - l2arc_write_buffers(spa, dev); - mutex_exit(&l2arc_dev_mtx); + l2arc_write_buffers(spa, dev, size); + spa_config_exit(spa, SCL_L2ARC, dev); } l2arc_thread_exit = 0; @@ -4099,6 +4312,22 @@ l2arc_feed_thread(void) thread_exit(); } +boolean_t +l2arc_vdev_present(vdev_t *vd) +{ + l2arc_dev_t *dev; + + mutex_enter(&l2arc_dev_mtx); + for (dev = list_head(l2arc_dev_list); dev != NULL; + dev = list_next(l2arc_dev_list, dev)) { + if (dev->l2ad_vdev == vd) + break; + } + mutex_exit(&l2arc_dev_mtx); + + return (dev != NULL); +} + /* * Add a vdev for use by the L2ARC. By this point the spa has already * validated the vdev and opened it. @@ -4108,6 +4337,8 @@ l2arc_add_vdev(spa_t *spa, vdev_t *vd, uint64_t start, uint64_t end) { l2arc_dev_t *adddev; + ASSERT(!l2arc_vdev_present(vd)); + /* * Create a new l2arc device entry. */ @@ -4115,6 +4346,7 @@ l2arc_add_vdev(spa_t *spa, vdev_t *vd, uint64_t start, uint64_t end) adddev->l2ad_spa = spa; adddev->l2ad_vdev = vd; adddev->l2ad_write = l2arc_write_max; + adddev->l2ad_boost = l2arc_write_boost; adddev->l2ad_start = start; adddev->l2ad_end = end; adddev->l2ad_hand = adddev->l2ad_start; @@ -4149,12 +4381,6 @@ l2arc_remove_vdev(vdev_t *vd) { l2arc_dev_t *dev, *nextdev, *remdev = NULL; - /* - * We can only grab the spa config lock when cache device writes - * complete. - */ - ASSERT3U(l2arc_writes_sent, ==, l2arc_writes_done); - /* * Find the device by vdev */ @@ -4173,6 +4399,8 @@ l2arc_remove_vdev(vdev_t *vd) */ list_remove(l2arc_dev_list, remdev); l2arc_dev_last = NULL; /* may have been invalidated */ + atomic_dec_64(&l2arc_ndev); + mutex_exit(&l2arc_dev_mtx); /* * Clear all buflists and ARC references. L2ARC device flush. @@ -4181,13 +4409,10 @@ l2arc_remove_vdev(vdev_t *vd) list_destroy(remdev->l2ad_buflist); kmem_free(remdev->l2ad_buflist, sizeof (list_t)); kmem_free(remdev, sizeof (l2arc_dev_t)); - - atomic_dec_64(&l2arc_ndev); - mutex_exit(&l2arc_dev_mtx); } void -l2arc_init() +l2arc_init(void) { l2arc_thread_exit = 0; l2arc_ndev = 0; @@ -4206,20 +4431,18 @@ l2arc_init() offsetof(l2arc_dev_t, l2ad_node)); list_create(l2arc_free_on_write, sizeof (l2arc_data_free_t), offsetof(l2arc_data_free_t, l2df_list_node)); - - (void) thread_create(NULL, 0, l2arc_feed_thread, NULL, 0, &p0, - TS_RUN, minclsyspri); } void -l2arc_fini() +l2arc_fini(void) { - mutex_enter(&l2arc_feed_thr_lock); - cv_signal(&l2arc_feed_thr_cv); /* kick thread out of startup */ - l2arc_thread_exit = 1; - while (l2arc_thread_exit != 0) - cv_wait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock); - mutex_exit(&l2arc_feed_thr_lock); + /* + * This is called from dmu_fini(), which is called from spa_fini(); + * Because of this, we can assume that all l2arc devices have + * already been removed when the pools themselves were removed. + */ + + l2arc_do_free_on_write(); mutex_destroy(&l2arc_feed_thr_lock); cv_destroy(&l2arc_feed_thr_cv); @@ -4230,3 +4453,27 @@ l2arc_fini() list_destroy(l2arc_dev_list); list_destroy(l2arc_free_on_write); } + +void +l2arc_start(void) +{ + if (!(spa_mode & FWRITE)) + return; + + (void) thread_create(NULL, 0, l2arc_feed_thread, NULL, 0, &p0, + TS_RUN, minclsyspri); +} + +void +l2arc_stop(void) +{ + if (!(spa_mode & FWRITE)) + return; + + mutex_enter(&l2arc_feed_thr_lock); + cv_signal(&l2arc_feed_thr_cv); /* kick thread out of startup */ + l2arc_thread_exit = 1; + while (l2arc_thread_exit != 0) + cv_wait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock); + mutex_exit(&l2arc_feed_thr_lock); +} diff --git a/zfs/lib/libzpool/bplist.c b/zfs/lib/libzpool/bplist.c index 099d499c0..93b7741d7 100644 --- a/zfs/lib/libzpool/bplist.c +++ b/zfs/lib/libzpool/bplist.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)bplist.c 1.5 07/10/29 SMI" - #include #include @@ -181,7 +179,7 @@ bplist_iterate(bplist_t *bpl, uint64_t *itorp, blkptr_t *bp) } int -bplist_enqueue(bplist_t *bpl, blkptr_t *bp, dmu_tx_t *tx) +bplist_enqueue(bplist_t *bpl, const blkptr_t *bp, dmu_tx_t *tx) { uint64_t blk, off; blkptr_t *bparray; @@ -229,7 +227,7 @@ bplist_enqueue(bplist_t *bpl, blkptr_t *bp, dmu_tx_t *tx) * Deferred entry; will be written later by bplist_sync(). */ void -bplist_enqueue_deferred(bplist_t *bpl, blkptr_t *bp) +bplist_enqueue_deferred(bplist_t *bpl, const blkptr_t *bp) { bplist_q_t *bpq = kmem_alloc(sizeof (*bpq), KM_SLEEP); @@ -311,3 +309,41 @@ bplist_space(bplist_t *bpl, uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) return (err); } + +/* + * Return (in *dasizep) the amount of space on the deadlist which is: + * mintxg < blk_birth <= maxtxg + */ +int +bplist_space_birthrange(bplist_t *bpl, uint64_t mintxg, uint64_t maxtxg, + uint64_t *dasizep) +{ + uint64_t size = 0; + uint64_t itor = 0; + blkptr_t bp; + int err; + + /* + * As an optimization, if they want the whole txg range, just + * get bpl_bytes rather than iterating over the bps. + */ + if (mintxg < TXG_INITIAL && maxtxg == UINT64_MAX) { + mutex_enter(&bpl->bpl_lock); + err = bplist_hold(bpl); + if (err == 0) + *dasizep = bpl->bpl_phys->bpl_bytes; + mutex_exit(&bpl->bpl_lock); + return (err); + } + + while ((err = bplist_iterate(bpl, &itor, &bp)) == 0) { + if (bp.blk_birth > mintxg && bp.blk_birth <= maxtxg) { + size += + bp_get_dasize(dmu_objset_spa(bpl->bpl_mos), &bp); + } + } + if (err == ENOENT) + err = 0; + *dasizep = size; + return (err); +} diff --git a/zfs/lib/libzpool/dbuf.c b/zfs/lib/libzpool/dbuf.c index 08d17fb58..d04610317 100644 --- a/zfs/lib/libzpool/dbuf.c +++ b/zfs/lib/libzpool/dbuf.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dbuf.c 1.32 08/03/20 SMI" - #include #include #include @@ -39,12 +37,11 @@ static void dbuf_destroy(dmu_buf_impl_t *db); static int dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx); -static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, int checksum, - int compress, dmu_tx_t *tx); +static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx); static arc_done_func_t dbuf_write_ready; static arc_done_func_t dbuf_write_done; - -int zfs_mdcomp_disable = 0; +static zio_done_func_t dbuf_skip_write_ready; +static zio_done_func_t dbuf_skip_write_done; /* * Global data structures and functions for the dbuf cache. @@ -313,20 +310,18 @@ dbuf_verify(dmu_buf_impl_t *db) ASSERT3U(db->db.db_offset, ==, db->db_blkid * db->db.db_size); } - if (db->db_level == 0) { - /* we can be momentarily larger in dnode_set_blksz() */ - if (db->db_blkid != DB_BONUS_BLKID && dn) { - ASSERT3U(db->db.db_size, >=, dn->dn_datablksz); - } - if (db->db.db_object == DMU_META_DNODE_OBJECT) { - dbuf_dirty_record_t *dr = db->db_data_pending; - /* - * it should only be modified in syncing - * context, so make sure we only have - * one copy of the data. - */ - ASSERT(dr == NULL || dr->dt.dl.dr_data == db->db_buf); - } + /* + * We can't assert that db_size matches dn_datablksz because it + * can be momentarily different when another thread is doing + * dnode_set_blksz(). + */ + if (db->db_level == 0 && db->db.db_object == DMU_META_DNODE_OBJECT) { + dbuf_dirty_record_t *dr = db->db_data_pending; + /* + * It should only be modified in syncing context, so + * make sure we only have one copy of the data. + */ + ASSERT(dr == NULL || dr->dt.dl.dr_data == db->db_buf); } /* verify db->db_blkptr */ @@ -403,7 +398,8 @@ dbuf_set_data(dmu_buf_impl_t *db, arc_buf_t *buf) } else { dbuf_evict_user(db); db->db.db_data = NULL; - db->db_state = DB_UNCACHED; + if (db->db_state != DB_NOFILL) + db->db_state = DB_UNCACHED; } } @@ -456,26 +452,27 @@ dbuf_read_done(zio_t *zio, arc_buf_t *buf, void *vdb) static void dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags) { - blkptr_t *bp; + dnode_t *dn = db->db_dnode; zbookmark_t zb; uint32_t aflags = ARC_NOWAIT; + arc_buf_t *pbuf; ASSERT(!refcount_is_zero(&db->db_holds)); /* We need the struct_rwlock to prevent db_blkptr from changing. */ - ASSERT(RW_LOCK_HELD(&db->db_dnode->dn_struct_rwlock)); + ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock)); ASSERT(MUTEX_HELD(&db->db_mtx)); ASSERT(db->db_state == DB_UNCACHED); ASSERT(db->db_buf == NULL); if (db->db_blkid == DB_BONUS_BLKID) { - int bonuslen = db->db_dnode->dn_bonuslen; + int bonuslen = dn->dn_bonuslen; ASSERT3U(bonuslen, <=, db->db.db_size); db->db.db_data = zio_buf_alloc(DN_MAX_BONUSLEN); arc_space_consume(DN_MAX_BONUSLEN); if (bonuslen < DN_MAX_BONUSLEN) bzero(db->db.db_data, DN_MAX_BONUSLEN); - bcopy(DN_BONUS(db->db_dnode->dn_phys), db->db.db_data, + bcopy(DN_BONUS(dn->dn_phys), db->db.db_data, bonuslen); dbuf_update_data(db); db->db_state = DB_CACHED; @@ -483,21 +480,17 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags) return; } - if (db->db_level == 0 && dnode_block_freed(db->db_dnode, db->db_blkid)) - bp = NULL; - else - bp = db->db_blkptr; - - if (bp == NULL) - dprintf_dbuf(db, "blkptr: %s\n", "NULL"); - else - dprintf_dbuf_bp(db, bp, "%s", "blkptr:"); - - if (bp == NULL || BP_IS_HOLE(bp)) { + /* + * Recheck BP_IS_HOLE() after dnode_block_freed() in case dnode_sync() + * processes the delete record and clears the bp while we are waiting + * for the dn_mtx (resulting in a "no" from block_freed). + */ + if (db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr) || + (db->db_level == 0 && (dnode_block_freed(dn, db->db_blkid) || + BP_IS_HOLE(db->db_blkptr)))) { arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db); - ASSERT(bp == NULL || BP_IS_HOLE(bp)); - dbuf_set_data(db, arc_buf_alloc(db->db_dnode->dn_objset->os_spa, + dbuf_set_data(db, arc_buf_alloc(dn->dn_objset->os_spa, db->db.db_size, db, type)); bzero(db->db.db_data, db->db.db_size); db->db_state = DB_CACHED; @@ -509,6 +502,9 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags) db->db_state = DB_READ; mutex_exit(&db->db_mtx); + if (DBUF_IS_L2CACHEABLE(db)) + aflags |= ARC_L2CACHE; + zb.zb_objset = db->db_objset->os_dsl_dataset ? db->db_objset->os_dsl_dataset->ds_object : 0; zb.zb_object = db->db.db_object; @@ -517,10 +513,13 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags) dbuf_add_ref(db, NULL); /* ZIO_FLAG_CANFAIL callers have to check the parent zio's error */ - ASSERT3U(db->db_dnode->dn_type, <, DMU_OT_NUMTYPES); - (void) arc_read(zio, db->db_dnode->dn_objset->os_spa, bp, - db->db_level > 0 ? byteswap_uint64_array : - dmu_ot[db->db_dnode->dn_type].ot_byteswap, + + if (db->db_parent) + pbuf = db->db_parent->db_buf; + else + pbuf = db->db_objset->os_phys_buf; + + (void) arc_read(zio, dn->dn_objset->os_spa, db->db_blkptr, pbuf, dbuf_read_done, db, ZIO_PRIORITY_SYNC_READ, (*flags & DB_RF_CANFAIL) ? ZIO_FLAG_CANFAIL : ZIO_FLAG_MUSTSUCCEED, &aflags, &zb); @@ -541,11 +540,15 @@ dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags) */ ASSERT(!refcount_is_zero(&db->db_holds)); + if (db->db_state == DB_NOFILL) + return (EIO); + if ((flags & DB_RF_HAVESTRUCT) == 0) rw_enter(&db->db_dnode->dn_struct_rwlock, RW_READER); prefetch = db->db_level == 0 && db->db_blkid != DB_BONUS_BLKID && - (flags & DB_RF_NOPREFETCH) == 0 && db->db_dnode != NULL; + (flags & DB_RF_NOPREFETCH) == 0 && db->db_dnode != NULL && + DBUF_IS_CACHEABLE(db); mutex_enter(&db->db_mtx); if (db->db_state == DB_CACHED) { @@ -615,6 +618,8 @@ dbuf_noread(dmu_buf_impl_t *db) dbuf_set_data(db, arc_buf_alloc(db->db_dnode->dn_objset->os_spa, db->db.db_size, db, type)); db->db_state = DB_FILL; + } else if (db->db_state == DB_NOFILL) { + dbuf_set_data(db, NULL); } else { ASSERT3U(db->db_state, ==, DB_CACHED); } @@ -690,7 +695,8 @@ dbuf_unoverride(dbuf_dirty_record_t *dr) /* free this block */ if (!BP_IS_HOLE(&dr->dt.dl.dr_overridden_by)) { /* XXX can get silent EIO here */ - (void) arc_free(NULL, db->db_dnode->dn_objset->os_spa, + (void) dsl_free(NULL, + spa_get_dsl(db->db_dnode->dn_objset->os_spa), txg, &dr->dt.dl.dr_overridden_by, NULL, NULL, ARC_WAIT); } dr->dt.dl.dr_override_state = DR_NOT_OVERRIDDEN; @@ -705,22 +711,50 @@ dbuf_unoverride(dbuf_dirty_record_t *dr) arc_release(dr->dt.dl.dr_data, db); } +/* + * Evict (if its unreferenced) or clear (if its referenced) any level-0 + * data blocks in the free range, so that any future readers will find + * empty blocks. Also, if we happen accross any level-1 dbufs in the + * range that have not already been marked dirty, mark them dirty so + * they stay in memory. + */ void -dbuf_free_range(dnode_t *dn, uint64_t blkid, uint64_t nblks, dmu_tx_t *tx) +dbuf_free_range(dnode_t *dn, uint64_t start, uint64_t end, dmu_tx_t *tx) { dmu_buf_impl_t *db, *db_next; uint64_t txg = tx->tx_txg; + int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; + uint64_t first_l1 = start >> epbs; + uint64_t last_l1 = end >> epbs; - dprintf_dnode(dn, "blkid=%llu nblks=%llu\n", blkid, nblks); + if (end > dn->dn_maxblkid) { + end = dn->dn_maxblkid; + last_l1 = end >> epbs; + } + dprintf_dnode(dn, "start=%llu end=%llu\n", start, end); mutex_enter(&dn->dn_dbufs_mtx); for (db = list_head(&dn->dn_dbufs); db; db = db_next) { db_next = list_next(&dn->dn_dbufs, db); ASSERT(db->db_blkid != DB_BONUS_BLKID); + + if (db->db_level == 1 && + db->db_blkid >= first_l1 && db->db_blkid <= last_l1) { + mutex_enter(&db->db_mtx); + if (db->db_last_dirty && + db->db_last_dirty->dr_txg < txg) { + dbuf_add_ref(db, FTAG); + mutex_exit(&db->db_mtx); + dbuf_will_dirty(db, tx); + dbuf_rele(db, FTAG); + } else { + mutex_exit(&db->db_mtx); + } + } + if (db->db_level != 0) continue; dprintf_dbuf(db, "found buf %s\n", ""); - if (db->db_blkid < blkid || - db->db_blkid >= blkid+nblks) + if (db->db_blkid < start || db->db_blkid > end) continue; /* found a level 0 buffer in the range */ @@ -729,6 +763,7 @@ dbuf_free_range(dnode_t *dn, uint64_t blkid, uint64_t nblks, dmu_tx_t *tx) mutex_enter(&db->db_mtx); if (db->db_state == DB_UNCACHED || + db->db_state == DB_NOFILL || db->db_state == DB_EVICTING) { ASSERT(db->db.db_data == NULL); mutex_exit(&db->db_mtx); @@ -862,6 +897,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) objset_impl_t *os = dn->dn_objset; dbuf_dirty_record_t **drp, *dr; int drop_struct_lock = FALSE; + boolean_t do_free_accounting = B_FALSE; int txgoff = tx->tx_txg & TXG_MASK; ASSERT(tx->tx_txg != 0); @@ -897,7 +933,8 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) * syncing context don't bother holding ahead. */ ASSERT(db->db_level != 0 || - db->db_state == DB_CACHED || db->db_state == DB_FILL); + db->db_state == DB_CACHED || db->db_state == DB_FILL || + db->db_state == DB_NOFILL); mutex_enter(&dn->dn_mtx); /* @@ -966,22 +1003,13 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) if (db->db_blkid != DB_BONUS_BLKID) { /* * Update the accounting. + * Note: we delay "free accounting" until after we drop + * the db_mtx. This keeps us from grabbing other locks + * (and possibly deadlocking) in bp_get_dasize() while + * also holding the db_mtx. */ - if (dbuf_block_freeable(db)) { - blkptr_t *bp = db->db_blkptr; - int64_t willfree = (bp && !BP_IS_HOLE(bp)) ? - bp_get_dasize(os->os_spa, bp) : db->db.db_size; - /* - * This is only a guess -- if the dbuf is dirty - * in a previous txg, we don't know how much - * space it will use on disk yet. We should - * really have the struct_rwlock to access - * db_blkptr, but since this is just a guess, - * it's OK if we get an odd answer. - */ - dnode_willuse_space(dn, -willfree, tx); - } dnode_willuse_space(dn, db->db.db_size, tx); + do_free_accounting = dbuf_block_freeable(db); } /* @@ -993,22 +1021,26 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) if (db->db_level == 0) { void *data_old = db->db_buf; - if (db->db_blkid == DB_BONUS_BLKID) { - dbuf_fix_old_data(db, tx->tx_txg); - data_old = db->db.db_data; - } else if (db->db.db_object != DMU_META_DNODE_OBJECT) { - /* - * Release the data buffer from the cache so that we - * can modify it without impacting possible other users - * of this cached data block. Note that indirect - * blocks and private objects are not released until the - * syncing state (since they are only modified then). - */ - arc_release(db->db_buf, db); - dbuf_fix_old_data(db, tx->tx_txg); - data_old = db->db_buf; + if (db->db_state != DB_NOFILL) { + if (db->db_blkid == DB_BONUS_BLKID) { + dbuf_fix_old_data(db, tx->tx_txg); + data_old = db->db.db_data; + } else if (db->db.db_object != DMU_META_DNODE_OBJECT) { + /* + * Release the data buffer from the cache so + * that we can modify it without impacting + * possible other users of this cached data + * block. Note that indirect blocks and + * private objects are not released until the + * syncing state (since they are only modified + * then). + */ + arc_release(db->db_buf, db); + dbuf_fix_old_data(db, tx->tx_txg); + data_old = db->db_buf; + } + ASSERT(data_old != NULL); } - ASSERT(data_old != NULL); dr->dt.dl.dr_data = data_old; } else { mutex_init(&dr->dt.di.dr_mtx, NULL, MUTEX_DEFAULT, NULL); @@ -1049,11 +1081,19 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) mutex_exit(&dn->dn_mtx); dnode_setdirty(dn, tx); return (dr); - } - - if (db->db_level == 0) { - dnode_new_blkid(dn, db->db_blkid, tx); - ASSERT(dn->dn_maxblkid >= db->db_blkid); + } else if (do_free_accounting) { + blkptr_t *bp = db->db_blkptr; + int64_t willfree = (bp && !BP_IS_HOLE(bp)) ? + bp_get_dasize(os->os_spa, bp) : db->db.db_size; + /* + * This is only a guess -- if the dbuf is dirty + * in a previous txg, we don't know how much + * space it will use on disk yet. We should + * really have the struct_rwlock to access + * db_blkptr, but since this is just a guess, + * it's OK if we get an odd answer. + */ + dnode_willuse_space(dn, -willfree, tx); } if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) { @@ -1061,6 +1101,11 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) drop_struct_lock = TRUE; } + if (db->db_level == 0) { + dnode_new_blkid(dn, db->db_blkid, tx, drop_struct_lock); + ASSERT(dn->dn_maxblkid >= db->db_blkid); + } + if (db->db_level+1 < dn->dn_nlevels) { dmu_buf_impl_t *parent = db->db_parent; dbuf_dirty_record_t *di; @@ -1161,19 +1206,22 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx) list_remove(&dr->dr_parent->dt.di.dr_children, dr); mutex_exit(&dr->dr_parent->dt.di.dr_mtx); } else if (db->db_level+1 == dn->dn_nlevels) { - ASSERT3P(db->db_parent, ==, dn->dn_dbuf); + ASSERT(db->db_blkptr == NULL || db->db_parent == dn->dn_dbuf); mutex_enter(&dn->dn_mtx); list_remove(&dn->dn_dirty_records[txg & TXG_MASK], dr); mutex_exit(&dn->dn_mtx); } if (db->db_level == 0) { - dbuf_unoverride(dr); + if (db->db_state != DB_NOFILL) { + dbuf_unoverride(dr); - ASSERT(db->db_buf != NULL); - ASSERT(dr->dt.dl.dr_data != NULL); - if (dr->dt.dl.dr_data != db->db_buf) - VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, db) == 1); + ASSERT(db->db_buf != NULL); + ASSERT(dr->dt.dl.dr_data != NULL); + if (dr->dt.dl.dr_data != db->db_buf) + VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, + db) == 1); + } } else { ASSERT(db->db_buf != NULL); ASSERT(list_head(&dr->dt.di.dr_children) == NULL); @@ -1214,6 +1262,16 @@ dbuf_will_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) (void) dbuf_dirty(db, tx); } +void +dmu_buf_will_not_fill(dmu_buf_t *db_fake, dmu_tx_t *tx) +{ + dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake; + + db->db_state = DB_NOFILL; + + dmu_buf_will_fill(db_fake, tx); +} + void dmu_buf_will_fill(dmu_buf_t *db_fake, dmu_tx_t *tx) { @@ -1289,7 +1347,7 @@ dbuf_clear(dmu_buf_impl_t *db) db->db_state = DB_UNCACHED; } - ASSERT3U(db->db_state, ==, DB_UNCACHED); + ASSERT(db->db_state == DB_UNCACHED || db->db_state == DB_NOFILL); ASSERT(db->db_data_pending == NULL); db->db_state = DB_EVICTING; @@ -1533,6 +1591,7 @@ dbuf_prefetch(dnode_t *dn, uint64_t blkid) if (dbuf_findbp(dn, 0, blkid, TRUE, &db, &bp) == 0) { if (bp && !BP_IS_HOLE(bp)) { + arc_buf_t *pbuf; uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH; zbookmark_t zb; zb.zb_objset = dn->dn_objset->os_dsl_dataset ? @@ -1541,9 +1600,13 @@ dbuf_prefetch(dnode_t *dn, uint64_t blkid) zb.zb_level = 0; zb.zb_blkid = blkid; - (void) arc_read(NULL, dn->dn_objset->os_spa, bp, - dmu_ot[dn->dn_type].ot_byteswap, - NULL, NULL, ZIO_PRIORITY_ASYNC_READ, + if (db) + pbuf = db->db_buf; + else + pbuf = dn->dn_objset->os_phys_buf; + + (void) arc_read(NULL, dn->dn_objset->os_spa, + bp, pbuf, NULL, NULL, ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE, &aflags, &zb); } @@ -1709,7 +1772,8 @@ dbuf_rele(dmu_buf_impl_t *db, void *tag) * This is a special case: we never associated this * dbuf with any data allocated from the ARC. */ - ASSERT3U(db->db_state, ==, DB_UNCACHED); + ASSERT(db->db_state == DB_UNCACHED || + db->db_state == DB_NOFILL); dbuf_evict(db); } else if (arc_released(db->db_buf)) { arc_buf_t *buf = db->db_buf; @@ -1721,7 +1785,10 @@ dbuf_rele(dmu_buf_impl_t *db, void *tag) dbuf_evict(db); } else { VERIFY(arc_buf_remove_ref(db->db_buf, db) == 0); - mutex_exit(&db->db_mtx); + if (!DBUF_IS_CACHEABLE(db)) + dbuf_clear(db); + else + mutex_exit(&db->db_mtx); } } else { mutex_exit(&db->db_mtx); @@ -1857,15 +1924,8 @@ dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx) db->db_data_pending = dr; - arc_release(db->db_buf, db); mutex_exit(&db->db_mtx); - - /* - * XXX -- we should design a compression algorithm - * that specializes in arrays of bps. - */ - dbuf_write(dr, db->db_buf, ZIO_CHECKSUM_FLETCHER_4, - zfs_mdcomp_disable ? ZIO_COMPRESS_EMPTY : ZIO_COMPRESS_LZJB, tx); + dbuf_write(dr, db->db_buf, tx); zio = dr->dr_zio; mutex_enter(&dr->dt.di.dr_mtx); @@ -1883,7 +1943,6 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx) dnode_t *dn = db->db_dnode; objset_impl_t *os = dn->dn_objset; uint64_t txg = tx->tx_txg; - int checksum, compress; int blksz; ASSERT(dmu_tx_is_syncing(tx)); @@ -1902,7 +1961,7 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx) /* This buffer was freed and is now being re-filled */ ASSERT(db->db.db_data != dr->dt.dl.dr_data); } else { - ASSERT3U(db->db_state, ==, DB_CACHED); + ASSERT(db->db_state == DB_CACHED || db->db_state == DB_NOFILL); } DBUF_VERIFY(db); @@ -1968,6 +2027,7 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx) zio_fake.io_bp = db->db_blkptr; zio_fake.io_bp_orig = *db->db_blkptr; zio_fake.io_txg = txg; + zio_fake.io_flags = 0; *db->db_blkptr = dr->dt.dl.dr_overridden_by; dr->dt.dl.dr_override_state = DR_NOT_OVERRIDDEN; @@ -1975,8 +2035,12 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx) dr->dr_zio = &zio_fake; mutex_exit(&db->db_mtx); + ASSERT(!DVA_EQUAL(BP_IDENTITY(zio_fake.io_bp), + BP_IDENTITY(&zio_fake.io_bp_orig)) || + BP_IS_HOLE(zio_fake.io_bp)); + if (BP_IS_OLDER(&zio_fake.io_bp_orig, txg)) - dsl_dataset_block_kill(os->os_dsl_dataset, + (void) dsl_dataset_block_kill(os->os_dsl_dataset, &zio_fake.io_bp_orig, dn->dn_zio, tx); dbuf_write_ready(&zio_fake, db->db_buf, db); @@ -1985,54 +2049,38 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx) return; } - blksz = arc_buf_size(*datap); + if (db->db_state != DB_NOFILL) { + blksz = arc_buf_size(*datap); - if (dn->dn_object != DMU_META_DNODE_OBJECT) { - /* - * If this buffer is currently "in use" (i.e., there are - * active holds and db_data still references it), then make - * a copy before we start the write so that any modifications - * from the open txg will not leak into this write. - * - * NOTE: this copy does not need to be made for objects only - * modified in the syncing context (e.g. DNONE_DNODE blocks). - */ - if (refcount_count(&db->db_holds) > 1 && *datap == db->db_buf) { - arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db); - *datap = arc_buf_alloc(os->os_spa, blksz, db, type); - bcopy(db->db.db_data, (*datap)->b_data, blksz); + if (dn->dn_object != DMU_META_DNODE_OBJECT) { + /* + * If this buffer is currently "in use" (i.e., there + * are active holds and db_data still references it), + * then make a copy before we start the write so that + * any modifications from the open txg will not leak + * into this write. + * + * NOTE: this copy does not need to be made for + * objects only modified in the syncing context (e.g. + * DNONE_DNODE blocks). + */ + if (refcount_count(&db->db_holds) > 1 && + *datap == db->db_buf) { + arc_buf_contents_t type = + DBUF_GET_BUFC_TYPE(db); + *datap = + arc_buf_alloc(os->os_spa, blksz, db, type); + bcopy(db->db.db_data, (*datap)->b_data, blksz); + } } - } else { - /* - * Private object buffers are released here rather - * than in dbuf_dirty() since they are only modified - * in the syncing context and we don't want the - * overhead of making multiple copies of the data. - */ - arc_release(db->db_buf, db); - } - ASSERT(*datap != NULL); + ASSERT(*datap != NULL); + } db->db_data_pending = dr; mutex_exit(&db->db_mtx); - /* - * Allow dnode settings to override objset settings, - * except for metadata checksums. - */ - if (dmu_ot[dn->dn_type].ot_metadata) { - checksum = os->os_md_checksum; - compress = zio_compress_select(dn->dn_compress, - os->os_md_compress); - } else { - checksum = zio_checksum_select(dn->dn_checksum, - os->os_checksum); - compress = zio_compress_select(dn->dn_compress, - os->os_compress); - } - - dbuf_write(dr, *datap, checksum, compress, tx); + dbuf_write(dr, *datap, tx); ASSERT(!list_link_active(&dr->dr_dirty_node)); if (dn->dn_object == DMU_META_DNODE_OBJECT) @@ -2068,8 +2116,7 @@ dbuf_sync_list(list_t *list, dmu_tx_t *tx) } static void -dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, int checksum, - int compress, dmu_tx_t *tx) +dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx) { dmu_buf_impl_t *db = dr->dr_dbuf; dnode_t *dn = db->db_dnode; @@ -2077,8 +2124,23 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, int checksum, dmu_buf_impl_t *parent = db->db_parent; uint64_t txg = tx->tx_txg; zbookmark_t zb; + writeprops_t wp = { 0 }; zio_t *zio; - int zio_flags; + + if (!BP_IS_HOLE(db->db_blkptr) && + (db->db_level > 0 || dn->dn_type == DMU_OT_DNODE)) { + /* + * Private object buffers are released here rather + * than in dbuf_dirty() since they are only modified + * in the syncing context and we don't want the + * overhead of making multiple copies of the data. + */ + arc_release(data, db); + } else if (db->db_state != DB_NOFILL) { + ASSERT(arc_released(data)); + /* XXX why do we need to thaw here? */ + arc_buf_thaw(data); + } if (parent != dn->dn_dbuf) { ASSERT(parent && parent->db_data_pending); @@ -2101,17 +2163,52 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, int checksum, zb.zb_level = db->db_level; zb.zb_blkid = db->db_blkid; - zio_flags = ZIO_FLAG_MUSTSUCCEED; - if (dmu_ot[dn->dn_type].ot_metadata || zb.zb_level != 0) - zio_flags |= ZIO_FLAG_METADATA; + wp.wp_type = dn->dn_type; + wp.wp_level = db->db_level; + wp.wp_copies = os->os_copies; + wp.wp_dncompress = dn->dn_compress; + wp.wp_oscompress = os->os_compress; + wp.wp_dnchecksum = dn->dn_checksum; + wp.wp_oschecksum = os->os_checksum; + if (BP_IS_OLDER(db->db_blkptr, txg)) - dsl_dataset_block_kill( + (void) dsl_dataset_block_kill( os->os_dsl_dataset, db->db_blkptr, zio, tx); - dr->dr_zio = arc_write(zio, os->os_spa, checksum, compress, - dmu_get_replication_level(os, &zb, dn->dn_type), txg, - db->db_blkptr, data, dbuf_write_ready, dbuf_write_done, db, - ZIO_PRIORITY_ASYNC_WRITE, zio_flags, &zb); + if (db->db_state == DB_NOFILL) { + zio_prop_t zp = { 0 }; + + write_policy(os->os_spa, &wp, &zp); + dr->dr_zio = zio_write(zio, os->os_spa, + txg, db->db_blkptr, NULL, + db->db.db_size, &zp, dbuf_skip_write_ready, + dbuf_skip_write_done, db, ZIO_PRIORITY_ASYNC_WRITE, + ZIO_FLAG_MUSTSUCCEED, &zb); + } else { + dr->dr_zio = arc_write(zio, os->os_spa, &wp, + DBUF_IS_L2CACHEABLE(db), txg, db->db_blkptr, + data, dbuf_write_ready, dbuf_write_done, db, + ZIO_PRIORITY_ASYNC_WRITE, ZIO_FLAG_MUSTSUCCEED, &zb); + } +} + +/* wrapper function for dbuf_write_ready bypassing ARC */ +static void +dbuf_skip_write_ready(zio_t *zio) +{ + blkptr_t *bp = zio->io_bp; + + if (!BP_IS_GANG(bp)) + zio_skip_write(zio); + + dbuf_write_ready(zio, NULL, zio->io_private); +} + +/* wrapper function for dbuf_write_done bypassing ARC */ +static void +dbuf_skip_write_done(zio_t *zio) +{ + dbuf_write_done(zio, NULL, zio->io_private); } /* ARGSUSED */ @@ -2121,27 +2218,33 @@ dbuf_write_ready(zio_t *zio, arc_buf_t *buf, void *vdb) dmu_buf_impl_t *db = vdb; dnode_t *dn = db->db_dnode; objset_impl_t *os = dn->dn_objset; + blkptr_t *bp = zio->io_bp; blkptr_t *bp_orig = &zio->io_bp_orig; uint64_t fill = 0; int old_size, new_size, i; + ASSERT(db->db_blkptr == bp); + dprintf_dbuf_bp(db, bp_orig, "bp_orig: %s", ""); old_size = bp_get_dasize(os->os_spa, bp_orig); - new_size = bp_get_dasize(os->os_spa, zio->io_bp); + new_size = bp_get_dasize(os->os_spa, bp); - dnode_diduse_space(dn, new_size-old_size); + dnode_diduse_space(dn, new_size - old_size); - if (BP_IS_HOLE(zio->io_bp)) { + if (BP_IS_HOLE(bp)) { dsl_dataset_t *ds = os->os_dsl_dataset; dmu_tx_t *tx = os->os_synctx; if (bp_orig->blk_birth == tx->tx_txg) - dsl_dataset_block_kill(ds, bp_orig, NULL, tx); - ASSERT3U(db->db_blkptr->blk_fill, ==, 0); + (void) dsl_dataset_block_kill(ds, bp_orig, zio, tx); + ASSERT3U(bp->blk_fill, ==, 0); return; } + ASSERT(BP_GET_TYPE(bp) == dn->dn_type); + ASSERT(BP_GET_LEVEL(bp) == db->db_level); + mutex_enter(&db->db_mtx); if (db->db_level == 0) { @@ -2161,32 +2264,31 @@ dbuf_write_ready(zio_t *zio, arc_buf_t *buf, void *vdb) fill = 1; } } else { - blkptr_t *bp = db->db.db_data; + blkptr_t *ibp = db->db.db_data; ASSERT3U(db->db.db_size, ==, 1<dn_phys->dn_indblkshift); - for (i = db->db.db_size >> SPA_BLKPTRSHIFT; i > 0; i--, bp++) { - if (BP_IS_HOLE(bp)) + for (i = db->db.db_size >> SPA_BLKPTRSHIFT; i > 0; i--, ibp++) { + if (BP_IS_HOLE(ibp)) continue; - ASSERT3U(BP_GET_LSIZE(bp), ==, + ASSERT3U(BP_GET_LSIZE(ibp), ==, db->db_level == 1 ? dn->dn_datablksz : (1<dn_phys->dn_indblkshift)); - fill += bp->blk_fill; + fill += ibp->blk_fill; } } - db->db_blkptr->blk_fill = fill; - BP_SET_TYPE(db->db_blkptr, dn->dn_type); - BP_SET_LEVEL(db->db_blkptr, db->db_level); + bp->blk_fill = fill; mutex_exit(&db->db_mtx); - /* We must do this after we've set the bp's type and level */ - if (!DVA_EQUAL(BP_IDENTITY(zio->io_bp), BP_IDENTITY(bp_orig))) { + if (zio->io_flags & ZIO_FLAG_IO_REWRITE) { + ASSERT(DVA_EQUAL(BP_IDENTITY(bp), BP_IDENTITY(bp_orig))); + } else { dsl_dataset_t *ds = os->os_dsl_dataset; dmu_tx_t *tx = os->os_synctx; if (bp_orig->blk_birth == tx->tx_txg) - dsl_dataset_block_kill(ds, bp_orig, NULL, tx); - dsl_dataset_block_born(ds, zio->io_bp, tx); + (void) dsl_dataset_block_kill(ds, bp_orig, zio, tx); + dsl_dataset_block_born(ds, bp, tx); } } @@ -2214,12 +2316,15 @@ dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb) ASSERT(db->db_blkid != DB_BONUS_BLKID); ASSERT(dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN); - if (dr->dt.dl.dr_data != db->db_buf) - VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, db) == 1); - else if (!BP_IS_HOLE(db->db_blkptr)) - arc_set_callback(db->db_buf, dbuf_do_evict, db); - else - ASSERT(arc_released(db->db_buf)); + if (db->db_state != DB_NOFILL) { + if (dr->dt.dl.dr_data != db->db_buf) + VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, + db) == 1); + else if (!BP_IS_HOLE(db->db_blkptr)) + arc_set_callback(db->db_buf, dbuf_do_evict, db); + else + ASSERT(arc_released(db->db_buf)); + } } else { dnode_t *dn = db->db_dnode; diff --git a/zfs/lib/libzpool/dmu.c b/zfs/lib/libzpool/dmu.c index 8e1278eb1..b6205bd50 100644 --- a/zfs/lib/libzpool/dmu.c +++ b/zfs/lib/libzpool/dmu.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)dmu.c 1.30 07/11/09 SMI" - #include #include #include @@ -44,6 +42,7 @@ #include #ifdef _KERNEL #include +#include #endif const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = { @@ -84,6 +83,8 @@ const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = { { byteswap_uint8_array, TRUE, "ZFS SYSACL" }, { byteswap_uint8_array, TRUE, "FUID table" }, { byteswap_uint64_array, TRUE, "FUID table size" }, + { zap_byteswap, TRUE, "DSL dataset next clones"}, + { zap_byteswap, TRUE, "scrub work queue" }, }; int @@ -182,11 +183,13 @@ static int dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length, int read, void *tag, int *numbufsp, dmu_buf_t ***dbpp) { + dsl_pool_t *dp = NULL; dmu_buf_t **dbp; uint64_t blkid, nblks, i; uint32_t flags; int err; zio_t *zio; + hrtime_t start; ASSERT(length <= DMU_MAX_ACCESS); @@ -213,7 +216,11 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, } dbp = kmem_zalloc(sizeof (dmu_buf_t *) * nblks, KM_SLEEP); - zio = zio_root(dn->dn_objset->os_spa, NULL, NULL, TRUE); + if (dn->dn_objset->os_dsl_dataset) + dp = dn->dn_objset->os_dsl_dataset->ds_dir->dd_pool; + if (dp && dsl_pool_sync_context(dp)) + start = gethrtime(); + zio = zio_root(dn->dn_objset->os_spa, NULL, NULL, ZIO_FLAG_CANFAIL); blkid = dbuf_whichblock(dn, offset); for (i = 0; i < nblks; i++) { dmu_buf_impl_t *db = dbuf_hold(dn, blkid+i, tag); @@ -235,6 +242,9 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, /* wait for async i/o */ err = zio_wait(zio); + /* track read overhead when we are in sync context */ + if (dp && dsl_pool_sync_context(dp)) + dp->dp_read_overhead += gethrtime() - start; if (err) { dmu_buf_rele_array(dbp, nblks, tag); return (err); @@ -364,6 +374,155 @@ dmu_prefetch(objset_t *os, uint64_t object, uint64_t offset, uint64_t len) dnode_rele(dn, FTAG); } +static int +get_next_chunk(dnode_t *dn, uint64_t *offset, uint64_t limit) +{ + uint64_t len = *offset - limit; + uint64_t chunk_len = dn->dn_datablksz * DMU_MAX_DELETEBLKCNT; + uint64_t subchunk = + dn->dn_datablksz * EPB(dn->dn_indblkshift, SPA_BLKPTRSHIFT); + + ASSERT(limit <= *offset); + + if (len <= chunk_len) { + *offset = limit; + return (0); + } + + ASSERT(ISP2(subchunk)); + + while (*offset > limit) { + uint64_t initial_offset = P2ROUNDUP(*offset, subchunk); + uint64_t delta; + int err; + + /* skip over allocated data */ + err = dnode_next_offset(dn, + DNODE_FIND_HOLE|DNODE_FIND_BACKWARDS, offset, 1, 1, 0); + if (err == ESRCH) + *offset = limit; + else if (err) + return (err); + + ASSERT3U(*offset, <=, initial_offset); + *offset = P2ALIGN(*offset, subchunk); + delta = initial_offset - *offset; + if (delta >= chunk_len) { + *offset += delta - chunk_len; + return (0); + } + chunk_len -= delta; + + /* skip over unallocated data */ + err = dnode_next_offset(dn, + DNODE_FIND_BACKWARDS, offset, 1, 1, 0); + if (err == ESRCH) + *offset = limit; + else if (err) + return (err); + + if (*offset < limit) + *offset = limit; + ASSERT3U(*offset, <, initial_offset); + } + return (0); +} + +static int +dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset, + uint64_t length, boolean_t free_dnode) +{ + dmu_tx_t *tx; + uint64_t object_size, start, end, len; + boolean_t trunc = (length == DMU_OBJECT_END); + int align, err; + + align = 1 << dn->dn_datablkshift; + ASSERT(align > 0); + object_size = align == 1 ? dn->dn_datablksz : + (dn->dn_maxblkid + 1) << dn->dn_datablkshift; + + if (trunc || (end = offset + length) > object_size) + end = object_size; + if (end <= offset) + return (0); + length = end - offset; + + while (length) { + start = end; + err = get_next_chunk(dn, &start, offset); + if (err) + return (err); + len = trunc ? DMU_OBJECT_END : end - start; + + tx = dmu_tx_create(os); + dmu_tx_hold_free(tx, dn->dn_object, start, len); + err = dmu_tx_assign(tx, TXG_WAIT); + if (err) { + dmu_tx_abort(tx); + return (err); + } + + dnode_free_range(dn, start, trunc ? -1 : len, tx); + + if (start == 0 && free_dnode) { + ASSERT(trunc); + dnode_free(dn, tx); + } + + length -= end - start; + + dmu_tx_commit(tx); + end = start; + } + return (0); +} + +int +dmu_free_long_range(objset_t *os, uint64_t object, + uint64_t offset, uint64_t length) +{ + dnode_t *dn; + int err; + + err = dnode_hold(os->os, object, FTAG, &dn); + if (err != 0) + return (err); + err = dmu_free_long_range_impl(os, dn, offset, length, FALSE); + dnode_rele(dn, FTAG); + return (err); +} + +int +dmu_free_object(objset_t *os, uint64_t object) +{ + dnode_t *dn; + dmu_tx_t *tx; + int err; + + err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_ALLOCATED, + FTAG, &dn); + if (err != 0) + return (err); + if (dn->dn_nlevels == 1) { + tx = dmu_tx_create(os); + dmu_tx_hold_bonus(tx, object); + dmu_tx_hold_free(tx, dn->dn_object, 0, DMU_OBJECT_END); + err = dmu_tx_assign(tx, TXG_WAIT); + if (err == 0) { + dnode_free_range(dn, 0, DMU_OBJECT_END, tx); + dnode_free(dn, tx); + dmu_tx_commit(tx); + } else { + dmu_tx_abort(tx); + } + } else { + err = dmu_free_long_range_impl(os, dn, 0, DMU_OBJECT_END, TRUE); + } + dnode_rele(dn, FTAG); + return (err); +} + int dmu_free_range(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_tx_t *tx) @@ -479,6 +638,27 @@ dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_buf_rele_array(dbp, numbufs, FTAG); } +void +dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, + dmu_tx_t *tx) +{ + dmu_buf_t **dbp; + int numbufs, i; + + if (size == 0) + return; + + VERIFY(0 == dmu_buf_hold_array(os, object, offset, size, + FALSE, FTAG, &numbufs, &dbp)); + + for (i = 0; i < numbufs; i++) { + dmu_buf_t *db = dbp[i]; + + dmu_buf_will_not_fill(db, tx); + } + dmu_buf_rele_array(dbp, numbufs, FTAG); +} + #ifdef _KERNEL int dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size) @@ -609,9 +789,9 @@ dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, for (copied = 0; copied < tocpy; copied += PAGESIZE) { ASSERT3U(pp->p_offset, ==, db->db_offset + bufoff); thiscpy = MIN(PAGESIZE, tocpy - copied); - va = ppmapin(pp, PROT_READ, (caddr_t)-1); + va = zfs_map_page(pp, S_READ); bcopy(va, (char *)db->db_data + bufoff, thiscpy); - ppmapout(va); + zfs_unmap_page(pp, va); pp = pp->p_next; bufoff += PAGESIZE; } @@ -636,6 +816,22 @@ typedef struct { void *arg; } dmu_sync_arg_t; +/* ARGSUSED */ +static void +dmu_sync_ready(zio_t *zio, arc_buf_t *buf, void *varg) +{ + blkptr_t *bp = zio->io_bp; + + if (!BP_IS_HOLE(bp)) { + dmu_sync_arg_t *in = varg; + dbuf_dirty_record_t *dr = in->dr; + dmu_buf_impl_t *db = dr->dr_dbuf; + ASSERT(BP_GET_TYPE(bp) == db->db_dnode->dn_type); + ASSERT(BP_GET_LEVEL(bp) == 0); + bp->blk_fill = 1; + } +} + /* ARGSUSED */ static void dmu_sync_done(zio_t *zio, arc_buf_t *buf, void *varg) @@ -645,12 +841,6 @@ dmu_sync_done(zio_t *zio, arc_buf_t *buf, void *varg) dmu_buf_impl_t *db = dr->dr_dbuf; dmu_sync_cb_t *done = in->done; - if (!BP_IS_HOLE(zio->io_bp)) { - zio->io_bp->blk_fill = 1; - BP_SET_TYPE(zio->io_bp, db->db_dnode->dn_type); - BP_SET_LEVEL(zio->io_bp, 0); - } - mutex_enter(&db->db_mtx); ASSERT(dr->dt.dl.dr_override_state == DR_IN_DMU_SYNC); dr->dt.dl.dr_overridden_by = *zio->io_bp; /* structure assignment */ @@ -697,14 +887,13 @@ dmu_sync(zio_t *pio, dmu_buf_t *db_fake, dbuf_dirty_record_t *dr; dmu_sync_arg_t *in; zbookmark_t zb; + writeprops_t wp = { 0 }; zio_t *zio; - int zio_flags; int err; ASSERT(BP_IS_HOLE(bp)); ASSERT(txg != 0); - dprintf("dmu_sync txg=%llu, s,o,q %llu %llu %llu\n", txg, tx->tx_synced_txg, tx->tx_open_txg, tx->tx_quiesced_txg); @@ -809,16 +998,20 @@ dmu_sync(zio_t *pio, dmu_buf_t *db_fake, zb.zb_object = db->db.db_object; zb.zb_level = db->db_level; zb.zb_blkid = db->db_blkid; - zio_flags = ZIO_FLAG_MUSTSUCCEED; - if (dmu_ot[db->db_dnode->dn_type].ot_metadata || zb.zb_level != 0) - zio_flags |= ZIO_FLAG_METADATA; - zio = arc_write(pio, os->os_spa, - zio_checksum_select(db->db_dnode->dn_checksum, os->os_checksum), - zio_compress_select(db->db_dnode->dn_compress, os->os_compress), - dmu_get_replication_level(os, &zb, db->db_dnode->dn_type), - txg, bp, dr->dt.dl.dr_data, NULL, dmu_sync_done, in, - ZIO_PRIORITY_SYNC_WRITE, zio_flags, &zb); + wp.wp_type = db->db_dnode->dn_type; + wp.wp_level = db->db_level; + wp.wp_copies = os->os_copies; + wp.wp_dnchecksum = db->db_dnode->dn_checksum; + wp.wp_oschecksum = os->os_checksum; + wp.wp_dncompress = db->db_dnode->dn_compress; + wp.wp_oscompress = os->os_compress; + + ASSERT(BP_IS_HOLE(bp)); + + zio = arc_write(pio, os->os_spa, &wp, DBUF_IS_L2CACHEABLE(db), + txg, bp, dr->dt.dl.dr_data, dmu_sync_ready, dmu_sync_done, in, + ZIO_PRIORITY_SYNC_WRITE, ZIO_FLAG_MUSTSUCCEED, &zb); if (pio) { zio_nowait(zio); err = EINPROGRESS; @@ -872,21 +1065,6 @@ dmu_object_set_compress(objset_t *os, uint64_t object, uint8_t compress, dnode_rele(dn, FTAG); } -int -dmu_get_replication_level(objset_impl_t *os, - zbookmark_t *zb, dmu_object_type_t ot) -{ - int ncopies = os->os_copies; - - /* If it's the mos, it should have max copies set. */ - ASSERT(zb->zb_objset != 0 || - ncopies == spa_max_replication(os->os_spa)); - - if (dmu_ot[ot].ot_metadata || zb->zb_level != 0) - ncopies++; - return (MIN(ncopies, spa_max_replication(os->os_spa))); -} - int dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off) { @@ -912,7 +1090,7 @@ dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off) return (err); } - err = dnode_next_offset(dn, hole, off, 1, 1, 0); + err = dnode_next_offset(dn, (hole ? DNODE_FIND_HOLE : 0), off, 1, 1, 0); dnode_rele(dn, FTAG); return (err); diff --git a/zfs/lib/libzpool/dmu_object.c b/zfs/lib/libzpool/dmu_object.c index 7a2c9e356..1b9247d66 100644 --- a/zfs/lib/libzpool/dmu_object.c +++ b/zfs/lib/libzpool/dmu_object.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)dmu_object.c 1.3 06/10/31 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -54,7 +54,8 @@ dmu_object_alloc(objset_t *os, dmu_object_type_t ot, int blocksize, if (P2PHASE(object, L2_dnode_count) == 0) { uint64_t offset = restarted ? object << DNODE_SHIFT : 0; int error = dnode_next_offset(osi->os_meta_dnode, - B_TRUE, &offset, 2, DNODES_PER_BLOCK >> 2, 0); + DNODE_FIND_HOLE, + &offset, 2, DNODES_PER_BLOCK >> 2, 0); restarted = B_TRUE; if (error == 0) object = offset >> DNODE_SHIFT; @@ -139,6 +140,7 @@ dmu_object_free(objset_t *os, uint64_t object, dmu_tx_t *tx) return (err); ASSERT(dn->dn_type != DMU_OT_NONE); + dnode_free_range(dn, 0, DMU_OBJECT_END, tx); dnode_free(dn, tx); dnode_rele(dn, FTAG); @@ -152,7 +154,7 @@ dmu_object_next(objset_t *os, uint64_t *objectp, boolean_t hole, uint64_t txg) int error; error = dnode_next_offset(os->os->os_meta_dnode, - hole, &offset, 0, DNODES_PER_BLOCK, txg); + (hole ? DNODE_FIND_HOLE : 0), &offset, 0, DNODES_PER_BLOCK, txg); *objectp = offset >> DNODE_SHIFT; diff --git a/zfs/lib/libzpool/dmu_objset.c b/zfs/lib/libzpool/dmu_objset.c index 829df52a4..7981e0682 100644 --- a/zfs/lib/libzpool/dmu_objset.c +++ b/zfs/lib/libzpool/dmu_objset.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dmu_objset.c 1.37 08/04/27 SMI" - #include #include #include @@ -133,6 +131,34 @@ copies_changed_cb(void *arg, uint64_t newval) osi->os_copies = newval; } +static void +primary_cache_changed_cb(void *arg, uint64_t newval) +{ + objset_impl_t *osi = arg; + + /* + * Inheritance and range checking should have been done by now. + */ + ASSERT(newval == ZFS_CACHE_ALL || newval == ZFS_CACHE_NONE || + newval == ZFS_CACHE_METADATA); + + osi->os_primary_cache = newval; +} + +static void +secondary_cache_changed_cb(void *arg, uint64_t newval) +{ + objset_impl_t *osi = arg; + + /* + * Inheritance and range checking should have been done by now. + */ + ASSERT(newval == ZFS_CACHE_ALL || newval == ZFS_CACHE_NONE || + newval == ZFS_CACHE_METADATA); + + osi->os_secondary_cache = newval; +} + void dmu_objset_byteswap(void *buf, size_t size) { @@ -149,7 +175,7 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, objset_impl_t **osip) { objset_impl_t *osi; - int i, err, checksum; + int i, err; ASSERT(ds == NULL || MUTEX_HELD(&ds->ds_opening_lock)); @@ -165,19 +191,26 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, zb.zb_object = 0; zb.zb_level = -1; zb.zb_blkid = 0; + if (DMU_OS_IS_L2CACHEABLE(osi)) + aflags |= ARC_L2CACHE; dprintf_bp(osi->os_rootbp, "reading %s", ""); - err = arc_read(NULL, spa, osi->os_rootbp, - dmu_ot[DMU_OT_OBJSET].ot_byteswap, + /* + * NB: when bprewrite scrub can change the bp, + * and this is called from dmu_objset_open_ds_os, the bp + * could change, and we'll need a lock. + */ + err = arc_read_nolock(NULL, spa, osi->os_rootbp, arc_getbuf_func, &osi->os_phys_buf, ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL, &aflags, &zb); if (err) { kmem_free(osi, sizeof (objset_impl_t)); + /* convert checksum errors into IO errors */ + if (err == ECKSUM) + err = EIO; return (err); } osi->os_phys = osi->os_phys_buf->b_data; - if (ds == NULL || dsl_dataset_is_snapshot(ds) == 0) - arc_release(osi->os_phys_buf, &osi->os_phys_buf); } else { osi->os_phys_buf = arc_buf_alloc(spa, sizeof (objset_phys_t), &osi->os_phys_buf, ARC_BUFC_METADATA); @@ -188,18 +221,26 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, /* * Note: the changed_cb will be called once before the register * func returns, thus changing the checksum/compression from the - * default (fletcher2/off). Snapshots don't need to know, and - * registering would complicate clone promotion. + * default (fletcher2/off). Snapshots don't need to know about + * checksum/compression/copies. */ - if (ds && ds->ds_phys->ds_num_children == 0) { - err = dsl_prop_register(ds, "checksum", - checksum_changed_cb, osi); + if (ds) { + err = dsl_prop_register(ds, "primarycache", + primary_cache_changed_cb, osi); if (err == 0) - err = dsl_prop_register(ds, "compression", - compression_changed_cb, osi); - if (err == 0) - err = dsl_prop_register(ds, "copies", - copies_changed_cb, osi); + err = dsl_prop_register(ds, "secondarycache", + secondary_cache_changed_cb, osi); + if (!dsl_dataset_is_snapshot(ds)) { + if (err == 0) + err = dsl_prop_register(ds, "checksum", + checksum_changed_cb, osi); + if (err == 0) + err = dsl_prop_register(ds, "compression", + compression_changed_cb, osi); + if (err == 0) + err = dsl_prop_register(ds, "copies", + copies_changed_cb, osi); + } if (err) { VERIFY(arc_buf_remove_ref(osi->os_phys_buf, &osi->os_phys_buf) == 1); @@ -211,24 +252,12 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, osi->os_checksum = ZIO_CHECKSUM_FLETCHER_4; osi->os_compress = ZIO_COMPRESS_LZJB; osi->os_copies = spa_max_replication(spa); + osi->os_primary_cache = ZFS_CACHE_ALL; + osi->os_secondary_cache = ZFS_CACHE_ALL; } - osi->os_zil = zil_alloc(&osi->os, &osi->os_phys->os_zil_header); - - /* - * Metadata always gets compressed and checksummed. - * If the data checksum is multi-bit correctable, and it's not - * a ZBT-style checksum, then it's suitable for metadata as well. - * Otherwise, the metadata checksum defaults to fletcher4. - */ - checksum = osi->os_checksum; - - if (zio_checksum_table[checksum].ci_correctable && - !zio_checksum_table[checksum].ci_zbt) - osi->os_md_checksum = checksum; - else - osi->os_md_checksum = ZIO_CHECKSUM_FLETCHER_4; - osi->os_md_compress = ZIO_COMPRESS_LZJB; + osi->os_zil_header = osi->os_phys->os_zil_header; + osi->os_zil = zil_alloc(&osi->os, &osi->os_zil_header); for (i = 0; i < TXG_SIZE; i++) { list_create(&osi->os_dirty_dnodes[i], sizeof (dnode_t), @@ -265,20 +294,23 @@ static int dmu_objset_open_ds_os(dsl_dataset_t *ds, objset_t *os, dmu_objset_type_t type) { objset_impl_t *osi; - int err; mutex_enter(&ds->ds_opening_lock); osi = dsl_dataset_get_user_ptr(ds); if (osi == NULL) { + int err; + err = dmu_objset_open_impl(dsl_dataset_get_spa(ds), ds, &ds->ds_phys->ds_bp, &osi); - if (err) + if (err) { + mutex_exit(&ds->ds_opening_lock); return (err); + } } mutex_exit(&ds->ds_opening_lock); os->os = osi; - os->os_mode = DS_MODE_NONE; + os->os_mode = DS_MODE_NOHOLD; if (type != DMU_OST_ANY && type != os->os->os_phys->os_type) return (EINVAL); @@ -309,21 +341,28 @@ dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, dsl_dataset_t *ds; int err; - ASSERT(mode != DS_MODE_NONE); + ASSERT(DS_MODE_TYPE(mode) == DS_MODE_USER || + DS_MODE_TYPE(mode) == DS_MODE_OWNER); os = kmem_alloc(sizeof (objset_t), KM_SLEEP); - err = dsl_dataset_open(name, mode, os, &ds); + if (DS_MODE_TYPE(mode) == DS_MODE_USER) + err = dsl_dataset_hold(name, os, &ds); + else + err = dsl_dataset_own(name, mode, os, &ds); if (err) { kmem_free(os, sizeof (objset_t)); return (err); } err = dmu_objset_open_ds_os(ds, os, type); - os->os_mode = mode; if (err) { + if (DS_MODE_TYPE(mode) == DS_MODE_USER) + dsl_dataset_rele(ds, os); + else + dsl_dataset_disown(ds, os); kmem_free(os, sizeof (objset_t)); - dsl_dataset_close(ds, mode, os); } else { + os->os_mode = mode; *osp = os; } return (err); @@ -332,8 +371,14 @@ dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, void dmu_objset_close(objset_t *os) { - if (os->os_mode != DS_MODE_NONE) - dsl_dataset_close(os->os->os_dsl_dataset, os->os_mode, os); + ASSERT(DS_MODE_TYPE(os->os_mode) == DS_MODE_USER || + DS_MODE_TYPE(os->os_mode) == DS_MODE_OWNER || + DS_MODE_TYPE(os->os_mode) == DS_MODE_NOHOLD); + + if (DS_MODE_TYPE(os->os_mode) == DS_MODE_USER) + dsl_dataset_rele(os->os->os_dsl_dataset, os); + else if (DS_MODE_TYPE(os->os_mode) == DS_MODE_OWNER) + dsl_dataset_disown(os->os->os_dsl_dataset, os); kmem_free(os, sizeof (objset_t)); } @@ -389,13 +434,19 @@ dmu_objset_evict(dsl_dataset_t *ds, void *arg) ASSERT(list_head(&osi->os_free_dnodes[i]) == NULL); } - if (ds && ds->ds_phys->ds_num_children == 0) { - VERIFY(0 == dsl_prop_unregister(ds, "checksum", - checksum_changed_cb, osi)); - VERIFY(0 == dsl_prop_unregister(ds, "compression", - compression_changed_cb, osi)); - VERIFY(0 == dsl_prop_unregister(ds, "copies", - copies_changed_cb, osi)); + if (ds) { + if (!dsl_dataset_is_snapshot(ds)) { + VERIFY(0 == dsl_prop_unregister(ds, "checksum", + checksum_changed_cb, osi)); + VERIFY(0 == dsl_prop_unregister(ds, "compression", + compression_changed_cb, osi)); + VERIFY(0 == dsl_prop_unregister(ds, "copies", + copies_changed_cb, osi)); + } + VERIFY(0 == dsl_prop_unregister(ds, "primarycache", + primary_cache_changed_cb, osi)); + VERIFY(0 == dsl_prop_unregister(ds, "secondarycache", + secondary_cache_changed_cb, osi)); } /* @@ -530,8 +581,7 @@ dmu_objset_create_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) dsobj = dsl_dataset_create_sync(dd, oa->lastname, oa->clone_parent, oa->flags, cr, tx); - VERIFY(0 == dsl_dataset_open_obj(dd->dd_pool, dsobj, NULL, - DS_MODE_STANDARD | DS_MODE_READONLY, FTAG, &ds)); + VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool, dsobj, FTAG, &ds)); bp = dsl_dataset_get_blkptr(ds); if (BP_IS_HOLE(bp)) { objset_impl_t *osi; @@ -547,7 +597,7 @@ dmu_objset_create_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) spa_history_internal_log(LOG_DS_CREATE, dd->dd_pool->dp_spa, tx, cr, "dataset = %llu", dsobj); - dsl_dataset_close(ds, DS_MODE_STANDARD | DS_MODE_READONLY, FTAG); + dsl_dataset_rele(ds, FTAG); } int @@ -606,17 +656,16 @@ dmu_objset_destroy(const char *name) * but the replay log objset is modified in open context. */ error = dmu_objset_open(name, DMU_OST_ANY, - DS_MODE_EXCLUSIVE|DS_MODE_READONLY, &os); + DS_MODE_OWNER|DS_MODE_READONLY|DS_MODE_INCONSISTENT, &os); if (error == 0) { dsl_dataset_t *ds = os->os->os_dsl_dataset; zil_destroy(dmu_objset_zil(os), B_FALSE); + error = dsl_dataset_destroy(ds, os); /* * dsl_dataset_destroy() closes the ds. - * os is just used as the tag after it's freed. */ kmem_free(os, sizeof (objset_t)); - error = dsl_dataset_destroy(ds, os); } return (error); @@ -633,7 +682,7 @@ dmu_objset_rollback(objset_t *os) ds = os->os->os_dsl_dataset; - if (!dsl_dataset_tryupgrade(ds, DS_MODE_STANDARD, DS_MODE_EXCLUSIVE)) { + if (!dsl_dataset_tryown(ds, TRUE, os)) { dmu_objset_close(os); return (EBUSY); } @@ -645,7 +694,7 @@ dmu_objset_rollback(objset_t *os) * actually implicitly called dmu_objset_evict(), thus freeing * the objset_impl_t. */ - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, os); + dsl_dataset_disown(ds, os); kmem_free(os, sizeof (objset_t)); return (err); } @@ -668,7 +717,6 @@ dmu_objset_snapshot_one(char *name, void *arg) { struct snaparg *sn = arg; objset_t *os; - dmu_objset_stats_t stat; int err; (void) strcpy(sn->failed, name); @@ -682,15 +730,12 @@ dmu_objset_snapshot_one(char *name, void *arg) (err = zfs_secpolicy_snapshot_perms(name, CRED()))) return (err); - err = dmu_objset_open(name, DMU_OST_ANY, DS_MODE_STANDARD, &os); + err = dmu_objset_open(name, DMU_OST_ANY, DS_MODE_USER, &os); if (err != 0) return (err); - /* - * If the objset is in an inconsistent state, return busy. - */ - dmu_objset_fast_stat(os, &stat); - if (stat.dds_inconsistent) { + /* If the objset is in an inconsistent state, return busy */ + if (os->os->os_dsl_dataset->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) { dmu_objset_close(os); return (EBUSY); } @@ -798,49 +843,39 @@ dmu_objset_sync_dnodes(list_t *list, dmu_tx_t *tx) static void ready(zio_t *zio, arc_buf_t *abuf, void *arg) { + blkptr_t *bp = zio->io_bp; + blkptr_t *bp_orig = &zio->io_bp_orig; objset_impl_t *os = arg; - blkptr_t *bp = os->os_rootbp; dnode_phys_t *dnp = &os->os_phys->os_meta_dnode; - int i; - ASSERT(bp == zio->io_bp); + ASSERT(bp == os->os_rootbp); + ASSERT(BP_GET_TYPE(bp) == DMU_OT_OBJSET); + ASSERT(BP_GET_LEVEL(bp) == 0); /* * Update rootbp fill count. */ bp->blk_fill = 1; /* count the meta-dnode */ - for (i = 0; i < dnp->dn_nblkptr; i++) + for (int i = 0; i < dnp->dn_nblkptr; i++) bp->blk_fill += dnp->dn_blkptr[i].blk_fill; - BP_SET_TYPE(bp, DMU_OT_OBJSET); - BP_SET_LEVEL(bp, 0); - - /* We must do this after we've set the bp's type and level */ - if (!DVA_EQUAL(BP_IDENTITY(bp), - BP_IDENTITY(&zio->io_bp_orig))) { + if (zio->io_flags & ZIO_FLAG_IO_REWRITE) { + ASSERT(DVA_EQUAL(BP_IDENTITY(bp), BP_IDENTITY(bp_orig))); + } else { if (zio->io_bp_orig.blk_birth == os->os_synctx->tx_txg) - dsl_dataset_block_kill(os->os_dsl_dataset, - &zio->io_bp_orig, NULL, os->os_synctx); + (void) dsl_dataset_block_kill(os->os_dsl_dataset, + &zio->io_bp_orig, zio, os->os_synctx); dsl_dataset_block_born(os->os_dsl_dataset, bp, os->os_synctx); } } -/* ARGSUSED */ -static void -killer(zio_t *zio, arc_buf_t *abuf, void *arg) -{ - objset_impl_t *os = arg; - - ASSERT3U(zio->io_error, ==, 0); - arc_release(os->os_phys_buf, &os->os_phys_buf); -} - /* called from dsl */ void dmu_objset_sync(objset_impl_t *os, zio_t *pio, dmu_tx_t *tx) { int txgoff; zbookmark_t zb; + writeprops_t wp = { 0 }; zio_t *zio; list_t *list; dbuf_dirty_record_t *dr; @@ -865,18 +900,24 @@ dmu_objset_sync(objset_impl_t *os, zio_t *pio, dmu_tx_t *tx) */ zb.zb_objset = os->os_dsl_dataset ? os->os_dsl_dataset->ds_object : 0; zb.zb_object = 0; - zb.zb_level = -1; + zb.zb_level = -1; /* for block ordering; it's level 0 on disk */ zb.zb_blkid = 0; + + wp.wp_type = DMU_OT_OBJSET; + wp.wp_level = 0; /* on-disk BP level; see above */ + wp.wp_copies = os->os_copies; + wp.wp_oschecksum = os->os_checksum; + wp.wp_oscompress = os->os_compress; + if (BP_IS_OLDER(os->os_rootbp, tx->tx_txg)) { - dsl_dataset_block_kill(os->os_dsl_dataset, + (void) dsl_dataset_block_kill(os->os_dsl_dataset, os->os_rootbp, pio, tx); } - zio = arc_write(pio, os->os_spa, os->os_md_checksum, - os->os_md_compress, - dmu_get_replication_level(os, &zb, DMU_OT_OBJSET), - tx->tx_txg, os->os_rootbp, os->os_phys_buf, ready, killer, os, - ZIO_PRIORITY_ASYNC_WRITE, ZIO_FLAG_MUSTSUCCEED | ZIO_FLAG_METADATA, - &zb); + + arc_release(os->os_phys_buf, &os->os_phys_buf); + zio = arc_write(pio, os->os_spa, &wp, DMU_OS_IS_L2CACHEABLE(os), + tx->tx_txg, os->os_rootbp, os->os_phys_buf, ready, NULL, os, + ZIO_PRIORITY_ASYNC_WRITE, ZIO_FLAG_MUSTSUCCEED, &zb); /* * Sync meta-dnode - the parent IO for the sync is the root block @@ -900,6 +941,7 @@ dmu_objset_sync(objset_impl_t *os, zio_t *pio, dmu_tx_t *tx) * Free intent log blocks up to this tx. */ zil_sync(os->os_zil, tx); + os->os_phys->os_zil_header = os->os_zil_header; zio_nowait(zio); } @@ -1036,48 +1078,80 @@ dmu_dir_list_next(objset_t *os, int namelen, char *name, return (0); } +struct findarg { + int (*func)(char *, void *); + void *arg; +}; + +/* ARGSUSED */ +static int +findfunc(spa_t *spa, uint64_t dsobj, const char *dsname, void *arg) +{ + struct findarg *fa = arg; + return (fa->func((char *)dsname, fa->arg)); +} + /* * Find all objsets under name, and for each, call 'func(child_name, arg)'. + * Perhaps change all callers to use dmu_objset_find_spa()? */ int dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) +{ + struct findarg fa; + fa.func = func; + fa.arg = arg; + return (dmu_objset_find_spa(NULL, name, findfunc, &fa, flags)); +} + +/* + * Find all objsets under name, call func on each + */ +int +dmu_objset_find_spa(spa_t *spa, const char *name, + int func(spa_t *, uint64_t, const char *, void *), void *arg, int flags) { dsl_dir_t *dd; - objset_t *os; - uint64_t snapobj; + dsl_pool_t *dp; + dsl_dataset_t *ds; zap_cursor_t zc; zap_attribute_t *attr; char *child; - int do_self, err; + uint64_t thisobj; + int err; - err = dsl_dir_open(name, FTAG, &dd, NULL); + if (name == NULL) + name = spa_name(spa); + err = dsl_dir_open_spa(spa, name, FTAG, &dd, NULL); if (err) return (err); - /* NB: the $MOS dir doesn't have a head dataset */ - do_self = (dd->dd_phys->dd_head_dataset_obj != 0); + /* Don't visit hidden ($MOS & $ORIGIN) objsets. */ + if (dd->dd_myname[0] == '$') { + dsl_dir_close(dd, FTAG); + return (0); + } + + thisobj = dd->dd_phys->dd_head_dataset_obj; attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP); + dp = dd->dd_pool; /* * Iterate over all children. */ if (flags & DS_FIND_CHILDREN) { - for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, + for (zap_cursor_init(&zc, dp->dp_meta_objset, dd->dd_phys->dd_child_dir_zapobj); zap_cursor_retrieve(&zc, attr) == 0; (void) zap_cursor_advance(&zc)) { ASSERT(attr->za_integer_length == sizeof (uint64_t)); ASSERT(attr->za_num_integers == 1); - /* - * No separating '/' because parent's name ends in /. - */ child = kmem_alloc(MAXPATHLEN, KM_SLEEP); - /* XXX could probably just use name here */ - dsl_dir_name(dd, child); + (void) strcpy(child, name); (void) strcat(child, "/"); (void) strcat(child, attr->za_name); - err = dmu_objset_find(child, func, arg, flags); + err = dmu_objset_find_spa(spa, child, func, arg, flags); kmem_free(child, MAXPATHLEN); if (err) break; @@ -1094,30 +1168,36 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) /* * Iterate over all snapshots. */ - if ((flags & DS_FIND_SNAPSHOTS) && - dmu_objset_open(name, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &os) == 0) { + if (flags & DS_FIND_SNAPSHOTS) { + if (!dsl_pool_sync_context(dp)) + rw_enter(&dp->dp_config_rwlock, RW_READER); + err = dsl_dataset_hold_obj(dp, thisobj, FTAG, &ds); + if (!dsl_pool_sync_context(dp)) + rw_exit(&dp->dp_config_rwlock); - snapobj = os->os->os_dsl_dataset->ds_phys->ds_snapnames_zapobj; - dmu_objset_close(os); + if (err == 0) { + uint64_t snapobj = ds->ds_phys->ds_snapnames_zapobj; + dsl_dataset_rele(ds, FTAG); - for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj); - zap_cursor_retrieve(&zc, attr) == 0; - (void) zap_cursor_advance(&zc)) { - ASSERT(attr->za_integer_length == sizeof (uint64_t)); - ASSERT(attr->za_num_integers == 1); + for (zap_cursor_init(&zc, dp->dp_meta_objset, snapobj); + zap_cursor_retrieve(&zc, attr) == 0; + (void) zap_cursor_advance(&zc)) { + ASSERT(attr->za_integer_length == + sizeof (uint64_t)); + ASSERT(attr->za_num_integers == 1); - child = kmem_alloc(MAXPATHLEN, KM_SLEEP); - /* XXX could probably just use name here */ - dsl_dir_name(dd, child); - (void) strcat(child, "@"); - (void) strcat(child, attr->za_name); - err = func(child, arg); - kmem_free(child, MAXPATHLEN); - if (err) - break; + child = kmem_alloc(MAXPATHLEN, KM_SLEEP); + (void) strcpy(child, name); + (void) strcat(child, "@"); + (void) strcat(child, attr->za_name); + err = func(spa, attr->za_first_integer, + child, arg); + kmem_free(child, MAXPATHLEN); + if (err) + break; + } + zap_cursor_fini(&zc); } - zap_cursor_fini(&zc); } dsl_dir_close(dd, FTAG); @@ -1129,8 +1209,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) /* * Apply to self if appropriate. */ - if (do_self) - err = func(name, arg); + err = func(spa, thisobj, name, arg); return (err); } diff --git a/zfs/lib/libdmu-ctl/dmu_send.c b/zfs/lib/libzpool/dmu_send.c similarity index 81% rename from zfs/lib/libdmu-ctl/dmu_send.c rename to zfs/lib/libzpool/dmu_send.c index 1c72f9507..857b9a343 100644 --- a/zfs/lib/libdmu-ctl/dmu_send.c +++ b/zfs/lib/libzpool/dmu_send.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dmu_send.c 1.14 08/04/27 SMI" - #include #include #include @@ -153,67 +151,59 @@ dump_dnode(struct backuparg *ba, uint64_t object, dnode_phys_t *dnp) (level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT))) static int -backup_cb(traverse_blk_cache_t *bc, spa_t *spa, void *arg) +backup_cb(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb, + const dnode_phys_t *dnp, void *arg) { struct backuparg *ba = arg; - uint64_t object = bc->bc_bookmark.zb_object; - int level = bc->bc_bookmark.zb_level; - uint64_t blkid = bc->bc_bookmark.zb_blkid; - blkptr_t *bp = bc->bc_blkptr.blk_birth ? &bc->bc_blkptr : NULL; dmu_object_type_t type = bp ? BP_GET_TYPE(bp) : DMU_OT_NONE; - void *data = bc->bc_data; int err = 0; if (issig(JUSTLOOKING) && issig(FORREAL)) return (EINTR); - ASSERT(data || bp == NULL); - - if (bp == NULL && object == 0) { - uint64_t span = BP_SPAN(bc->bc_dnode, level); - uint64_t dnobj = (blkid * span) >> DNODE_SHIFT; + if (bp == NULL && zb->zb_object == 0) { + uint64_t span = BP_SPAN(dnp, zb->zb_level); + uint64_t dnobj = (zb->zb_blkid * span) >> DNODE_SHIFT; err = dump_freeobjects(ba, dnobj, span >> DNODE_SHIFT); } else if (bp == NULL) { - uint64_t span = BP_SPAN(bc->bc_dnode, level); - err = dump_free(ba, object, blkid * span, span); - } else if (data && level == 0 && type == DMU_OT_DNODE) { - dnode_phys_t *blk = data; + uint64_t span = BP_SPAN(dnp, zb->zb_level); + err = dump_free(ba, zb->zb_object, zb->zb_blkid * span, span); + } else if (zb->zb_level > 0 || type == DMU_OT_OBJSET) { + return (0); + } else if (type == DMU_OT_DNODE) { + dnode_phys_t *blk; int i; int blksz = BP_GET_LSIZE(bp); + uint32_t aflags = ARC_WAIT; + arc_buf_t *abuf; + if (arc_read_nolock(NULL, spa, bp, + arc_getbuf_func, &abuf, ZIO_PRIORITY_ASYNC_READ, + ZIO_FLAG_CANFAIL, &aflags, zb) != 0) + return (EIO); + + blk = abuf->b_data; for (i = 0; i < blksz >> DNODE_SHIFT; i++) { - uint64_t dnobj = - (blkid << (DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i; + uint64_t dnobj = (zb->zb_blkid << + (DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i; err = dump_dnode(ba, dnobj, blk+i); if (err) break; } - } else if (level == 0 && - type != DMU_OT_DNODE && type != DMU_OT_OBJSET) { + (void) arc_buf_remove_ref(abuf, &abuf); + } else { /* it's a level-0 block of a regular object */ + uint32_t aflags = ARC_WAIT; + arc_buf_t *abuf; int blksz = BP_GET_LSIZE(bp); - if (data == NULL) { - uint32_t aflags = ARC_WAIT; - arc_buf_t *abuf; - zbookmark_t zb; - zb.zb_objset = ba->os->os->os_dsl_dataset->ds_object; - zb.zb_object = object; - zb.zb_level = level; - zb.zb_blkid = blkid; - (void) arc_read(NULL, spa, bp, - dmu_ot[type].ot_byteswap, arc_getbuf_func, &abuf, - ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_MUSTSUCCEED, - &aflags, &zb); + if (arc_read_nolock(NULL, spa, bp, + arc_getbuf_func, &abuf, ZIO_PRIORITY_ASYNC_READ, + ZIO_FLAG_CANFAIL, &aflags, zb) != 0) + return (EIO); - if (abuf) { - err = dump_data(ba, type, object, blkid * blksz, - blksz, abuf->b_data); - (void) arc_buf_remove_ref(abuf, &abuf); - } - } else { - err = dump_data(ba, type, object, blkid * blksz, - blksz, data); - } + err = dump_data(ba, type, zb->zb_object, zb->zb_blkid * blksz, + blksz, abuf->b_data); + (void) arc_buf_remove_ref(abuf, &abuf); } ASSERT(err == 0 || err == EINTR); @@ -241,15 +231,15 @@ dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin, return (EXDEV); if (fromorigin) { + dsl_pool_t *dp = ds->ds_dir->dd_pool; + if (fromsnap) return (EINVAL); - if (ds->ds_dir->dd_phys->dd_origin_obj != NULL) { - dsl_pool_t *dp = ds->ds_dir->dd_pool; + if (dsl_dir_is_clone(ds->ds_dir)) { rw_enter(&dp->dp_config_rwlock, RW_READER); - err = dsl_dataset_open_obj(dp, - ds->ds_dir->dd_phys->dd_origin_obj, NULL, - DS_MODE_NONE, FTAG, &fromds); + err = dsl_dataset_hold_obj(dp, + ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &fromds); rw_exit(&dp->dp_config_rwlock); if (err) return (err); @@ -279,7 +269,7 @@ dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin, if (fromds) fromtxg = fromds->ds_phys->ds_creation_txg; if (fromorigin) - dsl_dataset_close(fromds, DS_MODE_NONE, FTAG); + dsl_dataset_rele(fromds, FTAG); ba.drr = drr; ba.vp = vp; @@ -292,8 +282,7 @@ dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin, return (ba.err); } - err = traverse_dsl_dataset(ds, fromtxg, - ADVANCE_PRE | ADVANCE_HOLES | ADVANCE_DATA | ADVANCE_NOLOCK, + err = traverse_dataset(ds, fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH, backup_cb, &ba); if (err) { @@ -336,8 +325,10 @@ recv_full_sync_impl(dsl_pool_t *dp, uint64_t dsobj, dmu_objset_type_t type, { dsl_dataset_t *ds; - VERIFY(0 == dsl_dataset_open_obj(dp, dsobj, NULL, - DS_MODE_EXCLUSIVE, dmu_recv_tag, &ds)); + /* This should always work, since we just created it */ + /* XXX - create should return an owned ds */ + VERIFY(0 == dsl_dataset_own_obj(dp, dsobj, + DS_MODE_INCONSISTENT, dmu_recv_tag, &ds)); if (type != DMU_OST_NONE) { (void) dmu_objset_create_impl(dp->dp_spa, @@ -345,8 +336,7 @@ recv_full_sync_impl(dsl_pool_t *dp, uint64_t dsobj, dmu_objset_type_t type, } spa_history_internal_log(LOG_DS_REPLAY_FULL_SYNC, - ds->ds_dir->dd_pool->dp_spa, tx, cr, "dataset = %lld", - ds->ds_phys->ds_dir_obj); + dp->dp_spa, tx, cr, "dataset = %lld", dsobj); return (ds); } @@ -385,10 +375,8 @@ recv_full_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) { dsl_dir_t *dd = arg1; struct recvbeginsyncarg *rbsa = arg2; + uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags; uint64_t dsobj; - uint64_t flags = DS_FLAG_INCONSISTENT; - - flags |= rbsa->dsflags; dsobj = dsl_dataset_create_sync(dd, strrchr(rbsa->tofs, '/') + 1, rbsa->origin, flags, cr, tx); @@ -409,7 +397,7 @@ recv_full_existing_check(void *arg1, void *arg2, dmu_tx_t *tx) return (EINVAL); /* must not be a clone ds */ - if (ds->ds_prev != NULL) + if (dsl_dir_is_clone(ds->ds_dir)) return (EINVAL); err = dsl_dataset_destroy_check(ds, rbsa->tag, tx); @@ -435,10 +423,8 @@ recv_full_existing_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) dsl_dataset_t *ds = arg1; struct recvbeginsyncarg *rbsa = arg2; dsl_dir_t *dd = ds->ds_dir; + uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags; uint64_t dsobj; - uint64_t flags = DS_FLAG_INCONSISTENT; - - flags |= rbsa->dsflags; /* * NB: caller must provide an extra hold on the dsl_dir_t, so it @@ -447,7 +433,7 @@ recv_full_existing_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) */ dsl_dataset_destroy_sync(ds, rbsa->tag, cr, tx); - dsobj = dsl_dataset_create_sync_impl(dd, rbsa->origin, flags, tx); + dsobj = dsl_dataset_create_sync_dd(dd, rbsa->origin, flags, tx); rbsa->ds = recv_full_sync_impl(dd->dd_pool, dsobj, rbsa->origin ? DMU_OST_NONE : rbsa->type, cr, tx); @@ -501,21 +487,19 @@ recv_online_incremental_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) struct recvbeginsyncarg *rbsa = arg2; dsl_pool_t *dp = ohds->ds_dir->dd_pool; dsl_dataset_t *ods, *cds; + uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags; uint64_t dsobj; - uint64_t flags = DS_FLAG_INCONSISTENT; - - flags |= rbsa->dsflags; /* create the temporary clone */ - VERIFY(0 == dsl_dataset_open_obj(dp, ohds->ds_phys->ds_prev_snap_obj, - NULL, DS_MODE_STANDARD, FTAG, &ods)); + VERIFY(0 == dsl_dataset_hold_obj(dp, ohds->ds_phys->ds_prev_snap_obj, + FTAG, &ods)); dsobj = dsl_dataset_create_sync(ohds->ds_dir, rbsa->clonelastname, ods, flags, cr, tx); - dsl_dataset_close(ods, DS_MODE_STANDARD, FTAG); + dsl_dataset_rele(ods, FTAG); /* open the temporary clone */ - VERIFY(0 == dsl_dataset_open_obj(dp, dsobj, NULL, - DS_MODE_EXCLUSIVE, dmu_recv_tag, &cds)); + VERIFY(0 == dsl_dataset_own_obj(dp, dsobj, + DS_MODE_INCONSISTENT, dmu_recv_tag, &cds)); /* copy the refquota from the target fs to the clone */ if (ohds->ds_quota > 0) @@ -524,8 +508,7 @@ recv_online_incremental_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) rbsa->ds = cds; spa_history_internal_log(LOG_DS_REPLAY_INC_SYNC, - dp->dp_spa, tx, cr, "dataset = %lld", - cds->ds_phys->ds_dir_obj); + dp->dp_spa, tx, cr, "dataset = %lld", dsobj); } /* ARGSUSED */ @@ -539,7 +522,7 @@ recv_offline_incremental_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) spa_history_internal_log(LOG_DS_REPLAY_INC_SYNC, ds->ds_dir->dd_pool->dp_spa, tx, cr, "dataset = %lld", - ds->ds_phys->ds_dir_obj); + ds->ds_object); } /* @@ -599,8 +582,7 @@ dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb, */ if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE) && !online) { /* offline incremental receive */ - err = dsl_dataset_open(tofs, - DS_MODE_EXCLUSIVE, dmu_recv_tag, &ds); + err = dsl_dataset_own(tofs, 0, dmu_recv_tag, &ds); if (err) return (err); @@ -612,8 +594,7 @@ dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb, if (ds->ds_prev == NULL || ds->ds_prev->ds_phys->ds_guid != rbsa.fromguid) { - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, - dmu_recv_tag); + dsl_dataset_disown(ds, dmu_recv_tag); return (ENODEV); } (void) dsl_dataset_rollback(ds, DMU_OST_NONE); @@ -621,10 +602,9 @@ dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb, rbsa.force = B_FALSE; err = dsl_sync_task_do(ds->ds_dir->dd_pool, recv_incremental_check, - recv_offline_incremental_sync, - ds, &rbsa, 1); + recv_offline_incremental_sync, ds, &rbsa, 1); if (err) { - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, dmu_recv_tag); + dsl_dataset_disown(ds, dmu_recv_tag); return (err); } drc->drc_logical_ds = drc->drc_real_ds = ds; @@ -636,8 +616,7 @@ dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb, "%%%s", tosnap); /* open the dataset we are logically receiving into */ - err = dsl_dataset_open(tofs, - DS_MODE_STANDARD, dmu_recv_tag, &ds); + err = dsl_dataset_hold(tofs, dmu_recv_tag, &ds); if (err) return (err); @@ -646,7 +625,7 @@ dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb, recv_incremental_check, recv_online_incremental_sync, ds, &rbsa, 5); if (err) { - dsl_dataset_close(ds, DS_MODE_STANDARD, dmu_recv_tag); + dsl_dataset_rele(ds, dmu_recv_tag); return (err); } drc->drc_logical_ds = ds; @@ -666,27 +645,23 @@ dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb, } rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); - err = dsl_dataset_open_obj(dd->dd_pool, - dd->dd_phys->dd_head_dataset_obj, NULL, - DS_MODE_EXCLUSIVE | DS_MODE_INCONSISTENT, - FTAG, &ds); + err = dsl_dataset_own_obj(dd->dd_pool, + dd->dd_phys->dd_head_dataset_obj, + DS_MODE_INCONSISTENT, FTAG, &ds); rw_exit(&dd->dd_pool->dp_config_rwlock); if (err) { dsl_dir_close(dd, FTAG); return (err); } + dsl_dataset_make_exclusive(ds, FTAG); err = dsl_sync_task_do(dd->dd_pool, recv_full_existing_check, recv_full_existing_sync, ds, &rbsa, 5); - /* if successful, sync task closes the ds for us */ - if (err) - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); + dsl_dataset_disown(ds, FTAG); } else { err = dsl_sync_task_do(dd->dd_pool, recv_full_check, recv_full_sync, dd, &rbsa, 5); - if (err) - return (err); } dsl_dir_close(dd, FTAG); if (err) @@ -695,10 +670,6 @@ dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb, drc->drc_newfs = B_TRUE; } - /* downgrade our hold on the ds from EXCLUSIVE to PRIMARY */ - dsl_dataset_downgrade(drc->drc_real_ds, - DS_MODE_EXCLUSIVE, DS_MODE_PRIMARY); - return (0); } @@ -802,6 +773,7 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro) { int err; dmu_tx_t *tx; + void *data = NULL; err = dmu_object_info(os, drro->drr_object, NULL); @@ -820,6 +792,12 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro) return (EINVAL); } + if (drro->drr_bonuslen) { + data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8)); + if (ra->err) + return (ra->err); + } + tx = dmu_tx_create(os); if (err == ENOENT) { @@ -860,18 +838,13 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro) dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx); dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx); - if (drro->drr_bonuslen) { + if (data != NULL) { dmu_buf_t *db; - void *data; + VERIFY(0 == dmu_bonus_hold(os, drro->drr_object, FTAG, &db)); dmu_buf_will_dirty(db, tx); ASSERT3U(db->db_size, >=, drro->drr_bonuslen); - data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8)); - if (data == NULL) { - dmu_tx_commit(tx); - return (ra->err); - } bcopy(data, db->db_data, drro->drr_bonuslen); if (ra->byteswap) { dmu_ot[drro->drr_bonustype].ot_byteswap(db->db_data, @@ -896,23 +869,14 @@ restore_freeobjects(struct restorearg *ra, objset_t *os, for (obj = drrfo->drr_firstobj; obj < drrfo->drr_firstobj + drrfo->drr_numobjs; (void) dmu_object_next(os, &obj, FALSE, 0)) { - dmu_tx_t *tx; int err; if (dmu_object_info(os, obj, NULL) != 0) continue; - tx = dmu_tx_create(os); - dmu_tx_hold_bonus(tx, obj); - err = dmu_tx_assign(tx, TXG_WAIT); - if (err) { - dmu_tx_abort(tx); + err = dmu_free_object(os, obj); + if (err) return (err); - } - err = dmu_object_free(os, obj, tx); - dmu_tx_commit(tx); - if (err && err != ENOENT) - return (EINVAL); } return (0); } @@ -958,7 +922,6 @@ static int restore_free(struct restorearg *ra, objset_t *os, struct drr_free *drrf) { - dmu_tx_t *tx; int err; if (drrf->drr_length != -1ULL && @@ -968,18 +931,8 @@ restore_free(struct restorearg *ra, objset_t *os, if (dmu_object_info(os, drrf->drr_object, NULL) != 0) return (EINVAL); - tx = dmu_tx_create(os); - - dmu_tx_hold_free(tx, drrf->drr_object, + err = dmu_free_long_range(os, drrf->drr_object, drrf->drr_offset, drrf->drr_length); - err = dmu_tx_assign(tx, TXG_WAIT); - if (err) { - dmu_tx_abort(tx); - return (err); - } - err = dmu_free_range(os, drrf->drr_object, - drrf->drr_offset, drrf->drr_length, tx); - dmu_tx_commit(tx); return (err); } @@ -992,22 +945,14 @@ dmu_recv_abort_cleanup(dmu_recv_cookie_t *drc) * may be a clone) that we created */ (void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag); - if (drc->drc_real_ds != drc->drc_logical_ds) { - dsl_dataset_close(drc->drc_logical_ds, - DS_MODE_STANDARD, dmu_recv_tag); - } + if (drc->drc_real_ds != drc->drc_logical_ds) + dsl_dataset_rele(drc->drc_logical_ds, dmu_recv_tag); } else { /* * offline incremental: rollback to most recent snapshot. */ - int lmode = DS_MODE_PRIMARY; - if (dsl_dataset_tryupgrade(drc->drc_real_ds, - DS_MODE_PRIMARY, DS_MODE_EXCLUSIVE)) { - lmode = DS_MODE_EXCLUSIVE; - (void) dsl_dataset_rollback(drc->drc_real_ds, - DMU_OST_NONE); - } - dsl_dataset_close(drc->drc_real_ds, lmode, FTAG); + (void) dsl_dataset_rollback(drc->drc_real_ds, DMU_OST_NONE); + dsl_dataset_disown(drc->drc_real_ds, dmu_recv_tag); } } @@ -1186,64 +1131,51 @@ recv_end_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) int dmu_recv_end(dmu_recv_cookie_t *drc) { - int err = 0; - int lmode; + struct recvendsyncarg resa; + dsl_dataset_t *ds = drc->drc_logical_ds; + int err; /* * XXX hack; seems the ds is still dirty and - * dsl_pool_zil_clean() expects it to have a ds_user_ptr (and - * zil), but clone_swap() can close it. + * dsl_pool_zil_clean() expects it to have a ds_user_ptr + * (and zil), but clone_swap() can close it. */ - txg_wait_synced(drc->drc_real_ds->ds_dir->dd_pool, 0); + txg_wait_synced(ds->ds_dir->dd_pool, 0); - if (dsl_dataset_tryupgrade(drc->drc_real_ds, - DS_MODE_PRIMARY, DS_MODE_EXCLUSIVE)) { - lmode = DS_MODE_EXCLUSIVE; - } else { - dmu_recv_abort_cleanup(drc); - return (EBUSY); - } - - if (drc->drc_logical_ds != drc->drc_real_ds) { - if (err == 0 && dsl_dataset_tryupgrade(drc->drc_logical_ds, - DS_MODE_STANDARD, DS_MODE_EXCLUSIVE)) { - lmode = DS_MODE_EXCLUSIVE; - err = dsl_dataset_clone_swap(drc->drc_real_ds, - drc->drc_logical_ds, drc->drc_force); + if (ds != drc->drc_real_ds) { + /* we are doing an online recv */ + if (dsl_dataset_tryown(ds, FALSE, dmu_recv_tag)) { + err = dsl_dataset_clone_swap(drc->drc_real_ds, ds, + drc->drc_force); + if (err) + dsl_dataset_disown(ds, dmu_recv_tag); } else { - lmode = DS_MODE_STANDARD; err = EBUSY; + dsl_dataset_rele(ds, dmu_recv_tag); } - } - - if (err == 0) { - struct recvendsyncarg resa; - - resa.creation_time = drc->drc_drrb->drr_creation_time; - resa.toguid = drc->drc_drrb->drr_toguid; - resa.tosnap = drc->drc_tosnap; - - err = dsl_sync_task_do(drc->drc_real_ds->ds_dir->dd_pool, - recv_end_check, recv_end_sync, - drc->drc_logical_ds, &resa, 3); - if (err) { - if (drc->drc_newfs) { - ASSERT(drc->drc_logical_ds == drc->drc_real_ds); - (void) dsl_dataset_destroy(drc->drc_real_ds, - dmu_recv_tag); - return (err); - } else { - (void) dsl_dataset_rollback(drc->drc_logical_ds, - DMU_OST_NONE); - } - } - } - - if (drc->drc_logical_ds != drc->drc_real_ds) { - /* dsl_dataset_destroy() will close the ds */ + /* dsl_dataset_destroy() will disown the ds */ (void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag); + if (err) + return (err); } - /* close the hold from dmu_recv_begin */ - dsl_dataset_close(drc->drc_logical_ds, lmode, dmu_recv_tag); + + resa.creation_time = drc->drc_drrb->drr_creation_time; + resa.toguid = drc->drc_drrb->drr_toguid; + resa.tosnap = drc->drc_tosnap; + + err = dsl_sync_task_do(ds->ds_dir->dd_pool, + recv_end_check, recv_end_sync, ds, &resa, 3); + if (err) { + if (drc->drc_newfs) { + ASSERT(ds == drc->drc_real_ds); + (void) dsl_dataset_destroy(ds, dmu_recv_tag); + return (err); + } else { + (void) dsl_dataset_rollback(ds, DMU_OST_NONE); + } + } + + /* release the hold from dmu_recv_begin */ + dsl_dataset_disown(ds, dmu_recv_tag); return (err); } diff --git a/zfs/lib/libzpool/dmu_traverse.c b/zfs/lib/libzpool/dmu_traverse.c index 6d5723249..512401470 100644 --- a/zfs/lib/libzpool/dmu_traverse.c +++ b/zfs/lib/libzpool/dmu_traverse.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dmu_traverse.c 1.7 08/04/01 SMI" - #include #include #include @@ -35,510 +33,88 @@ #include #include #include -#include +#include -#define BP_SPAN_SHIFT(level, width) ((level) * (width)) - -#define BP_EQUAL(b1, b2) \ - (DVA_EQUAL(BP_IDENTITY(b1), BP_IDENTITY(b2)) && \ - (b1)->blk_birth == (b2)->blk_birth) - -/* - * Compare two bookmarks. - * - * For ADVANCE_PRE, the visitation order is: - * - * objset 0, 1, 2, ..., ZB_MAXOBJSET. - * object 0, 1, 2, ..., ZB_MAXOBJECT. - * blkoff 0, 1, 2, ... - * level ZB_MAXLEVEL, ..., 2, 1, 0. - * - * where blkoff = blkid << BP_SPAN_SHIFT(level, width), and thus a valid - * ordering vector is: - * - * < objset, object, blkoff, -level > - * - * For ADVANCE_POST, the starting offsets aren't sequential but ending - * offsets [blkoff = (blkid + 1) << BP_SPAN_SHIFT(level, width)] are. - * The visitation order is: - * - * objset 1, 2, ..., ZB_MAXOBJSET, 0. - * object 1, 2, ..., ZB_MAXOBJECT, 0. - * blkoff 1, 2, ... - * level 0, 1, 2, ..., ZB_MAXLEVEL. - * - * and thus a valid ordering vector is: - * - * < objset - 1, object - 1, blkoff, level > - * - * Both orderings can be expressed as: - * - * < objset + bias, object + bias, blkoff, level ^ bias > - * - * where 'bias' is either 0 or -1 (for ADVANCE_PRE or ADVANCE_POST) - * and 'blkoff' is (blkid - bias) << BP_SPAN_SHIFT(level, wshift). - * - * Special case: an objset's osphys is represented as level -1 of object 0. - * It is always either the very first or very last block we visit in an objset. - * Therefore, if either bookmark's level is -1, level alone determines order. - */ -static int -compare_bookmark(zbookmark_t *szb, zbookmark_t *ezb, dnode_phys_t *dnp, - int advance) -{ - int bias = (advance & ADVANCE_PRE) ? 0 : -1; - uint64_t sblkoff, eblkoff; - int slevel, elevel, wshift; - - if (szb->zb_objset + bias < ezb->zb_objset + bias) - return (-1); - - if (szb->zb_objset + bias > ezb->zb_objset + bias) - return (1); - - slevel = szb->zb_level; - elevel = ezb->zb_level; - - if ((slevel | elevel) < 0) - return ((slevel ^ bias) - (elevel ^ bias)); - - if (szb->zb_object + bias < ezb->zb_object + bias) - return (-1); - - if (szb->zb_object + bias > ezb->zb_object + bias) - return (1); - - if (dnp == NULL) - return (0); - - wshift = dnp->dn_indblkshift - SPA_BLKPTRSHIFT; - - sblkoff = (szb->zb_blkid - bias) << BP_SPAN_SHIFT(slevel, wshift); - eblkoff = (ezb->zb_blkid - bias) << BP_SPAN_SHIFT(elevel, wshift); - - if (sblkoff < eblkoff) - return (-1); - - if (sblkoff > eblkoff) - return (1); - - return ((elevel ^ bias) - (slevel ^ bias)); +#define SET_BOOKMARK(zb, objset, object, level, blkid) \ +{ \ + (zb)->zb_objset = objset; \ + (zb)->zb_object = object; \ + (zb)->zb_level = level; \ + (zb)->zb_blkid = blkid; \ } -#define SET_BOOKMARK(zb, objset, object, level, blkid) \ -{ \ - (zb)->zb_objset = objset; \ - (zb)->zb_object = object; \ - (zb)->zb_level = level; \ - (zb)->zb_blkid = blkid; \ -} +struct prefetch_data { + kmutex_t pd_mtx; + kcondvar_t pd_cv; + int pd_blks_max; + int pd_blks_fetched; + int pd_flags; + boolean_t pd_cancel; + boolean_t pd_exited; +}; -#define SET_BOOKMARK_LB(zb, level, blkid) \ -{ \ - (zb)->zb_level = level; \ - (zb)->zb_blkid = blkid; \ -} - -static int -advance_objset(zseg_t *zseg, uint64_t objset, int advance) -{ - zbookmark_t *zb = &zseg->seg_start; - - if (advance & ADVANCE_PRE) { - if (objset >= ZB_MAXOBJSET) - return (ERANGE); - SET_BOOKMARK(zb, objset, 0, -1, 0); - } else { - if (objset >= ZB_MAXOBJSET) - objset = 0; - SET_BOOKMARK(zb, objset, 1, 0, 0); - } - - if (compare_bookmark(zb, &zseg->seg_end, NULL, advance) > 0) - return (ERANGE); - - return (EAGAIN); -} - -static int -advance_object(zseg_t *zseg, uint64_t object, int advance) -{ - zbookmark_t *zb = &zseg->seg_start; - - if (advance & ADVANCE_PRE) { - if (object >= ZB_MAXOBJECT) { - SET_BOOKMARK(zb, zb->zb_objset + 1, 0, -1, 0); - } else { - SET_BOOKMARK(zb, zb->zb_objset, object, ZB_MAXLEVEL, 0); - } - } else { - if (zb->zb_object == 0) { - SET_BOOKMARK(zb, zb->zb_objset, 0, -1, 0); - } else { - if (object >= ZB_MAXOBJECT) - object = 0; - SET_BOOKMARK(zb, zb->zb_objset, object, 0, 0); - } - } - - if (compare_bookmark(zb, &zseg->seg_end, NULL, advance) > 0) - return (ERANGE); - - return (EAGAIN); -} - -static int -advance_from_osphys(zseg_t *zseg, int advance) -{ - zbookmark_t *zb = &zseg->seg_start; - - ASSERT(zb->zb_object == 0); - ASSERT(zb->zb_level == -1); - ASSERT(zb->zb_blkid == 0); - - if (advance & ADVANCE_PRE) { - SET_BOOKMARK_LB(zb, ZB_MAXLEVEL, 0); - } else { - if (zb->zb_objset == 0) - return (ERANGE); - SET_BOOKMARK(zb, zb->zb_objset + 1, 1, 0, 0); - } - - if (compare_bookmark(zb, &zseg->seg_end, NULL, advance) > 0) - return (ERANGE); - - return (EAGAIN); -} - -static int -advance_block(zseg_t *zseg, dnode_phys_t *dnp, int rc, int advance) -{ - zbookmark_t *zb = &zseg->seg_start; - int wshift = dnp->dn_indblkshift - SPA_BLKPTRSHIFT; - int maxlevel = dnp->dn_nlevels - 1; - int level = zb->zb_level; - uint64_t blkid = zb->zb_blkid; - - if (advance & ADVANCE_PRE) { - if (level > 0 && rc == 0) { - level--; - blkid <<= wshift; - } else { - blkid++; - - if ((blkid << BP_SPAN_SHIFT(level, wshift)) > - dnp->dn_maxblkid) - return (ERANGE); - - while (level < maxlevel) { - if (P2PHASE(blkid, 1ULL << wshift)) - break; - blkid >>= wshift; - level++; - } - } - } else { - if (level >= maxlevel || P2PHASE(blkid + 1, 1ULL << wshift)) { - blkid = (blkid + 1) << BP_SPAN_SHIFT(level, wshift); - level = 0; - } else { - blkid >>= wshift; - level++; - } - - while ((blkid << BP_SPAN_SHIFT(level, wshift)) > - dnp->dn_maxblkid) { - if (level == maxlevel) - return (ERANGE); - blkid >>= wshift; - level++; - } - } - SET_BOOKMARK_LB(zb, level, blkid); - - if (compare_bookmark(zb, &zseg->seg_end, dnp, advance) > 0) - return (ERANGE); - - return (EAGAIN); -} - -/* - * The traverse_callback function will call the function specified in th_func. - * In the event of an error the callee, specified by th_func, must return - * one of the following errors: - * - * EINTR - Indicates that the callee wants the traversal to - * abort immediately. - * ERESTART - The callee has acknowledged the error and would - * like to continue. - */ -static int -traverse_callback(traverse_handle_t *th, zseg_t *zseg, traverse_blk_cache_t *bc) -{ - /* - * Before we issue the callback, prune against maxtxg. - * - * We prune against mintxg before we get here because it's a big win. - * If a given block was born in txg 37, then we know that the entire - * subtree below that block must have been born in txg 37 or earlier. - * We can therefore lop off huge branches of the tree as we go. - * - * There's no corresponding optimization for maxtxg because knowing - * that bp->blk_birth >= maxtxg doesn't imply anything about the bp's - * children. In fact, the copy-on-write design of ZFS ensures that - * top-level blocks will pretty much always be new. - * - * Therefore, in the name of simplicity we don't prune against - * maxtxg until the last possible moment -- that being right now. - */ - if (bc->bc_errno == 0 && bc->bc_blkptr.blk_birth >= zseg->seg_maxtxg) - return (0); - - /* - * Debugging: verify that the order we visit things agrees with the - * order defined by compare_bookmark(). We don't check this for - * log blocks because there's no defined ordering for them; they're - * always visited (or not) as part of visiting the objset_phys_t. - */ - if (bc->bc_errno == 0 && bc != &th->th_zil_cache) { - zbookmark_t *zb = &bc->bc_bookmark; - zbookmark_t *szb = &zseg->seg_start; - zbookmark_t *ezb = &zseg->seg_end; - zbookmark_t *lzb = &th->th_lastcb; - dnode_phys_t *dnp = bc->bc_dnode; - - ASSERT(compare_bookmark(zb, ezb, dnp, th->th_advance) <= 0); - ASSERT(compare_bookmark(zb, szb, dnp, th->th_advance) == 0); - ASSERT(compare_bookmark(lzb, zb, dnp, th->th_advance) < 0 || - lzb->zb_level == ZB_NO_LEVEL); - *lzb = *zb; - } - - th->th_callbacks++; - return (th->th_func(bc, th->th_spa, th->th_arg)); -} - -static int -traverse_read(traverse_handle_t *th, traverse_blk_cache_t *bc, blkptr_t *bp, - dnode_phys_t *dnp) -{ - zbookmark_t *zb = &bc->bc_bookmark; - int error; - - th->th_hits++; - - bc->bc_dnode = dnp; - bc->bc_errno = 0; - - if (BP_EQUAL(&bc->bc_blkptr, bp)) - return (0); - - bc->bc_blkptr = *bp; - - if (bc->bc_data == NULL) - return (0); - - if (BP_IS_HOLE(bp)) { - ASSERT(th->th_advance & ADVANCE_HOLES); - return (0); - } - - if (compare_bookmark(zb, &th->th_noread, dnp, 0) == 0) { - error = EIO; - } else if (arc_tryread(th->th_spa, bp, bc->bc_data) == 0) { - error = 0; - th->th_arc_hits++; - } else { - error = zio_wait(zio_read(NULL, th->th_spa, bp, bc->bc_data, - BP_GET_LSIZE(bp), NULL, NULL, ZIO_PRIORITY_SYNC_READ, - th->th_zio_flags | ZIO_FLAG_DONT_CACHE, zb)); - - if (BP_SHOULD_BYTESWAP(bp) && error == 0) - (zb->zb_level > 0 ? byteswap_uint64_array : - dmu_ot[BP_GET_TYPE(bp)].ot_byteswap)(bc->bc_data, - BP_GET_LSIZE(bp)); - th->th_reads++; - } - - if (error) { - bc->bc_errno = error; - error = traverse_callback(th, NULL, bc); - ASSERT(error == EAGAIN || error == EINTR || error == ERESTART); - bc->bc_blkptr.blk_birth = -1ULL; - } - - dprintf("cache %02x error %d <%llu, %llu, %d, %llx>\n", - bc - &th->th_cache[0][0], error, - zb->zb_objset, zb->zb_object, zb->zb_level, zb->zb_blkid); - - return (error); -} - -static int -find_block(traverse_handle_t *th, zseg_t *zseg, dnode_phys_t *dnp, int depth) -{ - zbookmark_t *zb = &zseg->seg_start; - traverse_blk_cache_t *bc; - blkptr_t *bp = dnp->dn_blkptr; - int i, first, level; - int nbp = dnp->dn_nblkptr; - int minlevel = zb->zb_level; - int maxlevel = dnp->dn_nlevels - 1; - int wshift = dnp->dn_indblkshift - SPA_BLKPTRSHIFT; - int bp_shift = BP_SPAN_SHIFT(maxlevel - minlevel, wshift); - uint64_t blkid = zb->zb_blkid >> bp_shift; - int do_holes = (th->th_advance & ADVANCE_HOLES) && depth == ZB_DN_CACHE; - int rc; - - if (minlevel > maxlevel || blkid >= nbp) - return (ERANGE); - - for (level = maxlevel; level >= minlevel; level--) { - first = P2PHASE(blkid, 1ULL << wshift); - - for (i = first; i < nbp; i++) - if (bp[i].blk_birth > zseg->seg_mintxg || - BP_IS_HOLE(&bp[i]) && do_holes) - break; - - if (i != first) { - i--; - SET_BOOKMARK_LB(zb, level, blkid + (i - first)); - return (ENOTBLK); - } - - bc = &th->th_cache[depth][level]; - - SET_BOOKMARK(&bc->bc_bookmark, zb->zb_objset, zb->zb_object, - level, blkid); - - if (rc = traverse_read(th, bc, bp + i, dnp)) { - if (rc != EAGAIN) { - SET_BOOKMARK_LB(zb, level, blkid); - } - return (rc); - } - - if (BP_IS_HOLE(&bp[i])) { - SET_BOOKMARK_LB(zb, level, blkid); - th->th_lastcb.zb_level = ZB_NO_LEVEL; - return (0); - } - - nbp = 1 << wshift; - bp = bc->bc_data; - bp_shift -= wshift; - blkid = zb->zb_blkid >> bp_shift; - } - - return (0); -} - -static int -get_dnode(traverse_handle_t *th, uint64_t objset, dnode_phys_t *mdn, - uint64_t *objectp, dnode_phys_t **dnpp, uint64_t txg, int type, int depth) -{ - zseg_t zseg; - zbookmark_t *zb = &zseg.seg_start; - uint64_t object = *objectp; - int i, rc; - - SET_BOOKMARK(zb, objset, 0, 0, object / DNODES_PER_BLOCK); - SET_BOOKMARK(&zseg.seg_end, objset, 0, 0, ZB_MAXBLKID); - - zseg.seg_mintxg = txg; - zseg.seg_maxtxg = -1ULL; - - for (;;) { - rc = find_block(th, &zseg, mdn, depth); - - if (rc == EAGAIN || rc == EINTR || rc == ERANGE) - break; - - if (rc == 0 && zb->zb_level == 0) { - dnode_phys_t *dnp = th->th_cache[depth][0].bc_data; - for (i = 0; i < DNODES_PER_BLOCK; i++) { - object = (zb->zb_blkid * DNODES_PER_BLOCK) + i; - if (object >= *objectp && - dnp[i].dn_type != DMU_OT_NONE && - (type == -1 || dnp[i].dn_type == type)) { - *objectp = object; - *dnpp = &dnp[i]; - return (0); - } - } - } - - rc = advance_block(&zseg, mdn, rc, ADVANCE_PRE); - - if (rc == ERANGE) - break; - } - - if (rc == ERANGE) - *objectp = ZB_MAXOBJECT; - - return (rc); -} +struct traverse_data { + spa_t *td_spa; + uint64_t td_objset; + blkptr_t *td_rootbp; + uint64_t td_min_txg; + int td_flags; + struct prefetch_data *td_pfd; + blkptr_cb_t *td_func; + void *td_arg; +}; /* ARGSUSED */ static void traverse_zil_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg) { - traverse_handle_t *th = arg; - traverse_blk_cache_t *bc = &th->th_zil_cache; - zbookmark_t *zb = &bc->bc_bookmark; - zseg_t *zseg = list_head(&th->th_seglist); + struct traverse_data *td = arg; + zbookmark_t zb; - if (bp->blk_birth <= zseg->seg_mintxg) + if (bp->blk_birth == 0) return; - if (claim_txg != 0 || bp->blk_birth < spa_first_txg(th->th_spa)) { - zb->zb_object = 0; - zb->zb_blkid = bp->blk_cksum.zc_word[ZIL_ZC_SEQ]; - bc->bc_blkptr = *bp; - (void) traverse_callback(th, zseg, bc); - } + if (claim_txg == 0 && bp->blk_birth >= spa_first_txg(td->td_spa)) + return; + + zb.zb_objset = td->td_objset; + zb.zb_object = 0; + zb.zb_level = -1; + zb.zb_blkid = bp->blk_cksum.zc_word[ZIL_ZC_SEQ]; + VERIFY(0 == td->td_func(td->td_spa, bp, &zb, NULL, td->td_arg)); } /* ARGSUSED */ static void traverse_zil_record(zilog_t *zilog, lr_t *lrc, void *arg, uint64_t claim_txg) { - traverse_handle_t *th = arg; - traverse_blk_cache_t *bc = &th->th_zil_cache; - zbookmark_t *zb = &bc->bc_bookmark; - zseg_t *zseg = list_head(&th->th_seglist); + struct traverse_data *td = arg; if (lrc->lrc_txtype == TX_WRITE) { lr_write_t *lr = (lr_write_t *)lrc; blkptr_t *bp = &lr->lr_blkptr; + zbookmark_t zb; - if (bp->blk_birth <= zseg->seg_mintxg) + if (bp->blk_birth == 0) return; - if (claim_txg != 0 && bp->blk_birth >= claim_txg) { - zb->zb_object = lr->lr_foid; - zb->zb_blkid = lr->lr_offset / BP_GET_LSIZE(bp); - bc->bc_blkptr = *bp; - (void) traverse_callback(th, zseg, bc); - } + if (claim_txg == 0 || bp->blk_birth < claim_txg) + return; + + zb.zb_objset = td->td_objset; + zb.zb_object = lr->lr_foid; + zb.zb_level = BP_GET_LEVEL(bp); + zb.zb_blkid = lr->lr_offset / BP_GET_LSIZE(bp); + VERIFY(0 == td->td_func(td->td_spa, bp, &zb, NULL, td->td_arg)); } } static void -traverse_zil(traverse_handle_t *th, traverse_blk_cache_t *bc) +traverse_zil(struct traverse_data *td, zil_header_t *zh) { - spa_t *spa = th->th_spa; - dsl_pool_t *dp = spa_get_dsl(spa); - objset_phys_t *osphys = bc->bc_data; - zil_header_t *zh = &osphys->os_zil_header; uint64_t claim_txg = zh->zh_claim_txg; zilog_t *zilog; - ASSERT(bc == &th->th_cache[ZB_MDN_CACHE][ZB_MAXLEVEL - 1]); - ASSERT(bc->bc_bookmark.zb_level == -1); - /* * We only want to visit blocks that have been claimed but not yet * replayed (or, in read-only mode, blocks that *would* be claimed). @@ -546,372 +122,285 @@ traverse_zil(traverse_handle_t *th, traverse_blk_cache_t *bc) if (claim_txg == 0 && (spa_mode & FWRITE)) return; - th->th_zil_cache.bc_bookmark = bc->bc_bookmark; + zilog = zil_alloc(spa_get_dsl(td->td_spa)->dp_meta_objset, zh); - zilog = zil_alloc(dp->dp_meta_objset, zh); - - (void) zil_parse(zilog, traverse_zil_block, traverse_zil_record, th, + (void) zil_parse(zilog, traverse_zil_block, traverse_zil_record, td, claim_txg); zil_free(zilog); } static int -traverse_segment(traverse_handle_t *th, zseg_t *zseg, blkptr_t *mosbp) +traverse_visitbp(struct traverse_data *td, const dnode_phys_t *dnp, + arc_buf_t *pbuf, blkptr_t *bp, const zbookmark_t *zb) { - zbookmark_t *zb = &zseg->seg_start; - traverse_blk_cache_t *bc; - dnode_phys_t *dn, *dn_tmp; - int worklimit = 100; - int rc; + zbookmark_t czb; + int err = 0; + arc_buf_t *buf = NULL; + struct prefetch_data *pd = td->td_pfd; - dprintf("<%llu, %llu, %d, %llx>\n", - zb->zb_objset, zb->zb_object, zb->zb_level, zb->zb_blkid); - - bc = &th->th_cache[ZB_MOS_CACHE][ZB_MAXLEVEL - 1]; - dn = &((objset_phys_t *)bc->bc_data)->os_meta_dnode; - - SET_BOOKMARK(&bc->bc_bookmark, 0, 0, -1, 0); - - rc = traverse_read(th, bc, mosbp, dn); - - if (rc) /* If we get ERESTART, we've got nowhere left to go */ - return (rc == ERESTART ? EINTR : rc); - - ASSERT(dn->dn_nlevels < ZB_MAXLEVEL); - - if (zb->zb_objset != 0) { - uint64_t objset = zb->zb_objset; - dsl_dataset_phys_t *dsp; - - rc = get_dnode(th, 0, dn, &objset, &dn_tmp, 0, - DMU_OT_DSL_DATASET, ZB_MOS_CACHE); - - if (objset != zb->zb_objset) - rc = advance_objset(zseg, objset, th->th_advance); - - if (rc != 0) - return (rc); - - dsp = DN_BONUS(dn_tmp); - - bc = &th->th_cache[ZB_MDN_CACHE][ZB_MAXLEVEL - 1]; - dn = &((objset_phys_t *)bc->bc_data)->os_meta_dnode; - - SET_BOOKMARK(&bc->bc_bookmark, objset, 0, -1, 0); - - /* - * If we're traversing an open snapshot, we know that it - * can't be deleted (because it's open) and it can't change - * (because it's a snapshot). Therefore, once we've gotten - * from the uberblock down to the snapshot's objset_phys_t, - * we no longer need to synchronize with spa_sync(); we're - * traversing a completely static block tree from here on. - */ - if (th->th_advance & ADVANCE_NOLOCK) { - ASSERT(th->th_locked); - rw_exit(spa_traverse_rwlock(th->th_spa)); - th->th_locked = 0; - } - - rc = traverse_read(th, bc, &dsp->ds_bp, dn); - - if (rc != 0) { - if (rc == ERESTART) - rc = advance_objset(zseg, zb->zb_objset + 1, - th->th_advance); - return (rc); - } - - if (th->th_advance & ADVANCE_PRUNE) - zseg->seg_mintxg = - MAX(zseg->seg_mintxg, dsp->ds_prev_snap_txg); + if (bp->blk_birth == 0) { + err = td->td_func(td->td_spa, NULL, zb, dnp, td->td_arg); + return (err); } - if (zb->zb_level == -1) { - ASSERT(zb->zb_object == 0); - ASSERT(zb->zb_blkid == 0); - ASSERT(BP_GET_TYPE(&bc->bc_blkptr) == DMU_OT_OBJSET); - - if (bc->bc_blkptr.blk_birth > zseg->seg_mintxg) { - rc = traverse_callback(th, zseg, bc); - if (rc) { - ASSERT(rc == EINTR); - return (rc); - } - if ((th->th_advance & ADVANCE_ZIL) && - zb->zb_objset != 0) - traverse_zil(th, bc); - } - - return (advance_from_osphys(zseg, th->th_advance)); - } - - if (zb->zb_object != 0) { - uint64_t object = zb->zb_object; - - rc = get_dnode(th, zb->zb_objset, dn, &object, &dn_tmp, - zseg->seg_mintxg, -1, ZB_MDN_CACHE); - - if (object != zb->zb_object) - rc = advance_object(zseg, object, th->th_advance); - - if (rc != 0) - return (rc); - - dn = dn_tmp; - } - - if (zb->zb_level == ZB_MAXLEVEL) - zb->zb_level = dn->dn_nlevels - 1; - - for (;;) { - rc = find_block(th, zseg, dn, ZB_DN_CACHE); - - if (rc == EAGAIN || rc == EINTR || rc == ERANGE) - break; - - if (rc == 0) { - bc = &th->th_cache[ZB_DN_CACHE][zb->zb_level]; - ASSERT(bc->bc_dnode == dn); - ASSERT(bc->bc_blkptr.blk_birth <= mosbp->blk_birth); - rc = traverse_callback(th, zseg, bc); - if (rc) { - ASSERT(rc == EINTR); - return (rc); - } - if (BP_IS_HOLE(&bc->bc_blkptr)) { - ASSERT(th->th_advance & ADVANCE_HOLES); - rc = ENOTBLK; - } - } - - rc = advance_block(zseg, dn, rc, th->th_advance); - - if (rc == ERANGE) - break; - - /* - * Give spa_sync() a chance to run. - */ - if (th->th_locked && spa_traverse_wanted(th->th_spa)) { - th->th_syncs++; - return (EAGAIN); - } - - if (--worklimit == 0) - return (EAGAIN); - } - - if (rc == ERANGE) - rc = advance_object(zseg, zb->zb_object + 1, th->th_advance); - - return (rc); -} - -/* - * It is the caller's responsibility to ensure that the dsl_dataset_t - * doesn't go away during traversal. - */ -int -traverse_dsl_dataset(dsl_dataset_t *ds, uint64_t txg_start, int advance, - blkptr_cb_t func, void *arg) -{ - spa_t *spa = ds->ds_dir->dd_pool->dp_spa; - traverse_handle_t *th; - int err; - - th = traverse_init(spa, func, arg, advance, ZIO_FLAG_MUSTSUCCEED); - - traverse_add_objset(th, txg_start, -1ULL, ds->ds_object); - - while ((err = traverse_more(th)) == EAGAIN) - continue; - - traverse_fini(th); - return (err); -} - -int -traverse_zvol(objset_t *os, int advance, blkptr_cb_t func, void *arg) -{ - spa_t *spa = dmu_objset_spa(os); - traverse_handle_t *th; - int err; - - th = traverse_init(spa, func, arg, advance, ZIO_FLAG_CANFAIL); - - traverse_add_dnode(th, 0, -1ULL, dmu_objset_id(os), ZVOL_OBJ); - - while ((err = traverse_more(th)) == EAGAIN) - continue; - - traverse_fini(th); - return (err); -} - -int -traverse_more(traverse_handle_t *th) -{ - zseg_t *zseg = list_head(&th->th_seglist); - uint64_t save_txg; /* XXX won't be necessary with real itinerary */ - krwlock_t *rw = spa_traverse_rwlock(th->th_spa); - blkptr_t *mosbp = spa_get_rootblkptr(th->th_spa); - int rc; - - if (zseg == NULL) + if (bp->blk_birth <= td->td_min_txg) return (0); - th->th_restarts++; - - save_txg = zseg->seg_mintxg; - - rw_enter(rw, RW_READER); - th->th_locked = 1; - - rc = traverse_segment(th, zseg, mosbp); - ASSERT(rc == ERANGE || rc == EAGAIN || rc == EINTR); - - if (th->th_locked) - rw_exit(rw); - th->th_locked = 0; - - zseg->seg_mintxg = save_txg; - - if (rc == ERANGE) { - list_remove(&th->th_seglist, zseg); - kmem_free(zseg, sizeof (*zseg)); - return (EAGAIN); + if (pd && !pd->pd_exited && + ((pd->pd_flags & TRAVERSE_PREFETCH_DATA) || + BP_GET_TYPE(bp) == DMU_OT_DNODE || BP_GET_LEVEL(bp) > 0)) { + mutex_enter(&pd->pd_mtx); + ASSERT(pd->pd_blks_fetched >= 0); + while (pd->pd_blks_fetched == 0 && !pd->pd_exited) + cv_wait(&pd->pd_cv, &pd->pd_mtx); + pd->pd_blks_fetched--; + cv_broadcast(&pd->pd_cv); + mutex_exit(&pd->pd_mtx); } - return (rc); -} + if (td->td_flags & TRAVERSE_PRE) { + err = td->td_func(td->td_spa, bp, zb, dnp, td->td_arg); + if (err) + return (err); + } -/* - * Note: (mintxg, maxtxg) is an open interval; mintxg and maxtxg themselves - * are not included. The blocks covered by this segment will all have - * mintxg < birth < maxtxg. - */ -static void -traverse_add_segment(traverse_handle_t *th, uint64_t mintxg, uint64_t maxtxg, - uint64_t sobjset, uint64_t sobject, int slevel, uint64_t sblkid, - uint64_t eobjset, uint64_t eobject, int elevel, uint64_t eblkid) -{ - zseg_t *zseg; + if (BP_GET_LEVEL(bp) > 0) { + uint32_t flags = ARC_WAIT; + int i; + blkptr_t *cbp; + int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT; - zseg = kmem_alloc(sizeof (zseg_t), KM_SLEEP); + err = arc_read(NULL, td->td_spa, bp, pbuf, + arc_getbuf_func, &buf, + ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); + if (err) + return (err); - zseg->seg_mintxg = mintxg; - zseg->seg_maxtxg = maxtxg; + /* recursively visitbp() blocks below this */ + cbp = buf->b_data; + for (i = 0; i < epb; i++, cbp++) { + SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object, + zb->zb_level - 1, + zb->zb_blkid * epb + i); + err = traverse_visitbp(td, dnp, buf, cbp, &czb); + if (err) + break; + } + } else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) { + uint32_t flags = ARC_WAIT; + int i, j; + int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT; - zseg->seg_start.zb_objset = sobjset; - zseg->seg_start.zb_object = sobject; - zseg->seg_start.zb_level = slevel; - zseg->seg_start.zb_blkid = sblkid; + err = arc_read(NULL, td->td_spa, bp, pbuf, + arc_getbuf_func, &buf, + ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); + if (err) + return (err); - zseg->seg_end.zb_objset = eobjset; - zseg->seg_end.zb_object = eobject; - zseg->seg_end.zb_level = elevel; - zseg->seg_end.zb_blkid = eblkid; + /* recursively visitbp() blocks below this */ + dnp = buf->b_data; + for (i = 0; i < epb && err == 0; i++, dnp++) { + for (j = 0; j < dnp->dn_nblkptr; j++) { + SET_BOOKMARK(&czb, zb->zb_objset, + zb->zb_blkid * epb + i, + dnp->dn_nlevels - 1, j); + err = traverse_visitbp(td, dnp, buf, + (blkptr_t *)&dnp->dn_blkptr[j], &czb); + if (err) + break; + } + } + } else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) { + uint32_t flags = ARC_WAIT; + objset_phys_t *osp; + int j; - list_insert_tail(&th->th_seglist, zseg); -} + err = arc_read_nolock(NULL, td->td_spa, bp, + arc_getbuf_func, &buf, + ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); + if (err) + return (err); -void -traverse_add_dnode(traverse_handle_t *th, uint64_t mintxg, uint64_t maxtxg, - uint64_t objset, uint64_t object) -{ - if (th->th_advance & ADVANCE_PRE) - traverse_add_segment(th, mintxg, maxtxg, - objset, object, ZB_MAXLEVEL, 0, - objset, object, 0, ZB_MAXBLKID); - else - traverse_add_segment(th, mintxg, maxtxg, - objset, object, 0, 0, - objset, object, 0, ZB_MAXBLKID); -} + osp = buf->b_data; + /* + * traverse_zil is just here for zdb's leak checking. + * For other consumers, there will be no ZIL blocks. + */ + traverse_zil(td, &osp->os_zil_header); -void -traverse_add_objset(traverse_handle_t *th, uint64_t mintxg, uint64_t maxtxg, - uint64_t objset) -{ - if (th->th_advance & ADVANCE_PRE) - traverse_add_segment(th, mintxg, maxtxg, - objset, 0, -1, 0, - objset, ZB_MAXOBJECT, 0, ZB_MAXBLKID); - else - traverse_add_segment(th, mintxg, maxtxg, - objset, 1, 0, 0, - objset, 0, -1, 0); -} - -void -traverse_add_pool(traverse_handle_t *th, uint64_t mintxg, uint64_t maxtxg) -{ - if (th->th_advance & ADVANCE_PRE) - traverse_add_segment(th, mintxg, maxtxg, - 0, 0, -1, 0, - ZB_MAXOBJSET, ZB_MAXOBJECT, 0, ZB_MAXBLKID); - else - traverse_add_segment(th, mintxg, maxtxg, - 1, 1, 0, 0, - 0, 0, -1, 0); -} - -traverse_handle_t * -traverse_init(spa_t *spa, blkptr_cb_t func, void *arg, int advance, - int zio_flags) -{ - traverse_handle_t *th; - int d, l; - - th = kmem_zalloc(sizeof (*th), KM_SLEEP); - - th->th_spa = spa; - th->th_func = func; - th->th_arg = arg; - th->th_advance = advance; - th->th_lastcb.zb_level = ZB_NO_LEVEL; - th->th_noread.zb_level = ZB_NO_LEVEL; - th->th_zio_flags = zio_flags; - - list_create(&th->th_seglist, sizeof (zseg_t), - offsetof(zseg_t, seg_node)); - - for (d = 0; d < ZB_DEPTH; d++) { - for (l = 0; l < ZB_MAXLEVEL; l++) { - if ((advance & ADVANCE_DATA) || - l != 0 || d != ZB_DN_CACHE) - th->th_cache[d][l].bc_data = - zio_buf_alloc(SPA_MAXBLOCKSIZE); + for (j = 0; j < osp->os_meta_dnode.dn_nblkptr; j++) { + SET_BOOKMARK(&czb, zb->zb_objset, 0, + osp->os_meta_dnode.dn_nlevels - 1, j); + err = traverse_visitbp(td, &osp->os_meta_dnode, buf, + (blkptr_t *)&osp->os_meta_dnode.dn_blkptr[j], + &czb); + if (err) + break; } } - return (th); + if (buf) + (void) arc_buf_remove_ref(buf, &buf); + + if (err == 0 && (td->td_flags & TRAVERSE_POST)) + err = td->td_func(td->td_spa, bp, zb, dnp, td->td_arg); + + return (err); } -void -traverse_fini(traverse_handle_t *th) +/* ARGSUSED */ +static int +traverse_prefetcher(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb, + const dnode_phys_t *dnp, void *arg) { - int d, l; - zseg_t *zseg; + struct prefetch_data *pfd = arg; + uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH; - for (d = 0; d < ZB_DEPTH; d++) - for (l = 0; l < ZB_MAXLEVEL; l++) - if (th->th_cache[d][l].bc_data != NULL) - zio_buf_free(th->th_cache[d][l].bc_data, - SPA_MAXBLOCKSIZE); + ASSERT(pfd->pd_blks_fetched >= 0); + if (pfd->pd_cancel) + return (EINTR); - while ((zseg = list_head(&th->th_seglist)) != NULL) { - list_remove(&th->th_seglist, zseg); - kmem_free(zseg, sizeof (*zseg)); - } + if (bp == NULL || !((pfd->pd_flags & TRAVERSE_PREFETCH_DATA) || + BP_GET_TYPE(bp) == DMU_OT_DNODE || BP_GET_LEVEL(bp) > 0)) + return (0); - list_destroy(&th->th_seglist); + mutex_enter(&pfd->pd_mtx); + while (!pfd->pd_cancel && pfd->pd_blks_fetched >= pfd->pd_blks_max) + cv_wait(&pfd->pd_cv, &pfd->pd_mtx); + pfd->pd_blks_fetched++; + cv_broadcast(&pfd->pd_cv); + mutex_exit(&pfd->pd_mtx); - dprintf("%llu hit, %llu ARC, %llu IO, %llu cb, %llu sync, %llu again\n", - th->th_hits, th->th_arc_hits, th->th_reads, th->th_callbacks, - th->th_syncs, th->th_restarts); + (void) arc_read_nolock(NULL, spa, bp, NULL, NULL, + ZIO_PRIORITY_ASYNC_READ, + ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE, + &aflags, zb); - kmem_free(th, sizeof (*th)); + return (0); +} + +static void +traverse_prefetch_thread(void *arg) +{ + struct traverse_data *td_main = arg; + struct traverse_data td = *td_main; + zbookmark_t czb; + + td.td_func = traverse_prefetcher; + td.td_arg = td_main->td_pfd; + td.td_pfd = NULL; + + SET_BOOKMARK(&czb, td.td_objset, 0, -1, 0); + (void) traverse_visitbp(&td, NULL, NULL, td.td_rootbp, &czb); + + mutex_enter(&td_main->td_pfd->pd_mtx); + td_main->td_pfd->pd_exited = B_TRUE; + cv_broadcast(&td_main->td_pfd->pd_cv); + mutex_exit(&td_main->td_pfd->pd_mtx); +} + +/* + * NB: dataset must not be changing on-disk (eg, is a snapshot or we are + * in syncing context). + */ +static int +traverse_impl(spa_t *spa, uint64_t objset, blkptr_t *rootbp, + uint64_t txg_start, int flags, blkptr_cb_t func, void *arg) +{ + struct traverse_data td; + struct prefetch_data pd = { 0 }; + zbookmark_t czb; + int err; + + td.td_spa = spa; + td.td_objset = objset; + td.td_rootbp = rootbp; + td.td_min_txg = txg_start; + td.td_func = func; + td.td_arg = arg; + td.td_pfd = &pd; + td.td_flags = flags; + + pd.pd_blks_max = 100; + pd.pd_flags = flags; + mutex_init(&pd.pd_mtx, NULL, MUTEX_DEFAULT, NULL); + cv_init(&pd.pd_cv, NULL, CV_DEFAULT, NULL); + + if (!(flags & TRAVERSE_PREFETCH) || + 0 == taskq_dispatch(system_taskq, traverse_prefetch_thread, + &td, TQ_NOQUEUE)) + pd.pd_exited = B_TRUE; + + SET_BOOKMARK(&czb, objset, 0, -1, 0); + err = traverse_visitbp(&td, NULL, NULL, rootbp, &czb); + + mutex_enter(&pd.pd_mtx); + pd.pd_cancel = B_TRUE; + cv_broadcast(&pd.pd_cv); + while (!pd.pd_exited) + cv_wait(&pd.pd_cv, &pd.pd_mtx); + mutex_exit(&pd.pd_mtx); + + mutex_destroy(&pd.pd_mtx); + cv_destroy(&pd.pd_cv); + + return (err); +} + +/* + * NB: dataset must not be changing on-disk (eg, is a snapshot or we are + * in syncing context). + */ +int +traverse_dataset(dsl_dataset_t *ds, uint64_t txg_start, int flags, + blkptr_cb_t func, void *arg) +{ + return (traverse_impl(ds->ds_dir->dd_pool->dp_spa, ds->ds_object, + &ds->ds_phys->ds_bp, txg_start, flags, func, arg)); +} + +/* + * NB: pool must not be changing on-disk (eg, from zdb or sync context). + */ +int +traverse_pool(spa_t *spa, blkptr_cb_t func, void *arg) +{ + int err; + uint64_t obj; + dsl_pool_t *dp = spa_get_dsl(spa); + objset_t *mos = dp->dp_meta_objset; + + /* visit the MOS */ + err = traverse_impl(spa, 0, spa_get_rootblkptr(spa), + 0, TRAVERSE_PRE, func, arg); + if (err) + return (err); + + /* visit each dataset */ + for (obj = 1; err == 0; err = dmu_object_next(mos, &obj, FALSE, 0)) { + dmu_object_info_t doi; + + err = dmu_object_info(mos, obj, &doi); + if (err) + return (err); + + if (doi.doi_type == DMU_OT_DSL_DATASET) { + dsl_dataset_t *ds; + rw_enter(&dp->dp_config_rwlock, RW_READER); + err = dsl_dataset_hold_obj(dp, obj, FTAG, &ds); + rw_exit(&dp->dp_config_rwlock); + if (err) + return (err); + err = traverse_dataset(ds, + ds->ds_phys->ds_prev_snap_txg, TRAVERSE_PRE, + func, arg); + dsl_dataset_rele(ds, FTAG); + if (err) + return (err); + } + } + if (err == ESRCH) + err = 0; + return (err); } diff --git a/zfs/lib/libzpool/dmu_tx.c b/zfs/lib/libzpool/dmu_tx.c index 8c40c2680..bf560e565 100644 --- a/zfs/lib/libzpool/dmu_tx.c +++ b/zfs/lib/libzpool/dmu_tx.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dmu_tx.c 1.19 08/03/20 SMI" - #include #include #include @@ -179,7 +177,6 @@ dmu_tx_count_write(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) min_ibs = DN_MIN_INDBLKSHIFT; max_ibs = DN_MAX_INDBLKSHIFT; - /* * For i/o error checking, read the first and last level-0 * blocks (if they are not aligned), and all the level-1 blocks. @@ -187,9 +184,12 @@ dmu_tx_count_write(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) if (dn) { if (dn->dn_maxblkid == 0) { - err = dmu_tx_check_ioerr(NULL, dn, 0, 0); - if (err) - goto out; + if ((off > 0 || len < dn->dn_datablksz) && + off < dn->dn_datablksz) { + err = dmu_tx_check_ioerr(NULL, dn, 0, 0); + if (err) + goto out; + } } else { zio_t *zio = zio_root(dn->dn_objset->os_spa, NULL, NULL, ZIO_FLAG_CANFAIL); @@ -205,7 +205,7 @@ dmu_tx_count_write(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) /* last level-0 block */ end = (off+len-1) >> dn->dn_datablkshift; - if (end != start && + if (end != start && end <= dn->dn_maxblkid && P2PHASE(off+len, dn->dn_datablksz)) { err = dmu_tx_check_ioerr(zio, dn, 0, end); if (err) @@ -320,39 +320,25 @@ dmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len) static void dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) { - uint64_t blkid, nblks; - uint64_t space = 0, unref = 0; + uint64_t blkid, nblks, lastblk; + uint64_t space = 0, unref = 0, skipped = 0; dnode_t *dn = txh->txh_dnode; dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; spa_t *spa = txh->txh_tx->tx_pool->dp_spa; - int dirty; + int epbs; - /* - * We don't need to use any locking to check for dirtyness - * because it's OK if we get stale data -- the dnode may become - * dirty immediately after our check anyway. This is just a - * means to avoid the expensive count when we aren't sure we - * need it. We need to be able to deal with a dirty dnode. - */ - dirty = list_link_active(&dn->dn_dirty_link[0]) | - list_link_active(&dn->dn_dirty_link[1]) | - list_link_active(&dn->dn_dirty_link[2]) | - list_link_active(&dn->dn_dirty_link[3]); - if (dirty || dn->dn_assigned_txg || dn->dn_phys->dn_nlevels == 0) + if (dn->dn_nlevels == 0) return; /* - * the struct_rwlock protects us against dn_phys->dn_nlevels + * The struct_rwlock protects us against dn_nlevels * changing, in case (against all odds) we manage to dirty & * sync out the changes after we check for being dirty. - * also, dbuf_hold_impl() wants us to have the struct_rwlock. - * - * It's fine to use dn_datablkshift rather than the dn_phys - * equivalent because if it is changing, maxblkid==0 and we will - * bail. + * Also, dbuf_hold_level() wants us to have the struct_rwlock. */ rw_enter(&dn->dn_struct_rwlock, RW_READER); - if (dn->dn_phys->dn_maxblkid == 0) { + epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; + if (dn->dn_maxblkid == 0) { if (off == 0 && len >= dn->dn_datablksz) { blkid = 0; nblks = 1; @@ -362,24 +348,21 @@ dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) } } else { blkid = off >> dn->dn_datablkshift; - nblks = (off + len) >> dn->dn_datablkshift; + nblks = (len + dn->dn_datablksz - 1) >> dn->dn_datablkshift; - if (blkid >= dn->dn_phys->dn_maxblkid) { + if (blkid >= dn->dn_maxblkid) { rw_exit(&dn->dn_struct_rwlock); return; } - if (blkid + nblks > dn->dn_phys->dn_maxblkid) - nblks = dn->dn_phys->dn_maxblkid - blkid; + if (blkid + nblks > dn->dn_maxblkid) + nblks = dn->dn_maxblkid - blkid; - /* don't bother after 128,000 blocks */ - nblks = MIN(nblks, 128*1024); } - - if (dn->dn_phys->dn_nlevels == 1) { + if (dn->dn_nlevels == 1) { int i; for (i = 0; i < nblks; i++) { blkptr_t *bp = dn->dn_phys->dn_blkptr; - ASSERT3U(blkid + i, <, dn->dn_phys->dn_nblkptr); + ASSERT3U(blkid + i, <, dn->dn_nblkptr); bp += blkid + i; if (dsl_dataset_block_freeable(ds, bp->blk_birth)) { dprintf_bp(bp, "can free old%s", ""); @@ -390,51 +373,93 @@ dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) nblks = 0; } + /* + * Add in memory requirements of higher-level indirects. + * This assumes a worst-possible scenario for dn_nlevels. + */ + { + uint64_t blkcnt = 1 + ((nblks >> epbs) >> epbs); + int level = (dn->dn_nlevels > 1) ? 2 : 1; + + while (level++ < DN_MAX_LEVELS) { + txh->txh_memory_tohold += blkcnt << dn->dn_indblkshift; + blkcnt = 1 + (blkcnt >> epbs); + } + ASSERT(blkcnt <= dn->dn_nblkptr); + } + + lastblk = blkid + nblks - 1; while (nblks) { dmu_buf_impl_t *dbuf; - int err, epbs, blkoff, tochk; + uint64_t ibyte, new_blkid; + int epb = 1 << epbs; + int err, i, blkoff, tochk; + blkptr_t *bp; - epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; - blkoff = P2PHASE(blkid, 1<> epbs, TRUE, FTAG, &dbuf); - if (err == 0) { - int i; - blkptr_t *bp; - - err = dbuf_read(dbuf, NULL, - DB_RF_HAVESTRUCT | DB_RF_CANFAIL); - if (err != 0) { - txh->txh_tx->tx_err = err; - dbuf_rele(dbuf, FTAG); - break; - } - - bp = dbuf->db.db_data; - bp += blkoff; - - for (i = 0; i < tochk; i++) { - if (dsl_dataset_block_freeable(ds, - bp[i].blk_birth)) { - dprintf_bp(&bp[i], - "can free old%s", ""); - space += bp_get_dasize(spa, &bp[i]); - } - unref += BP_GET_ASIZE(bp); - } - dbuf_rele(dbuf, FTAG); + ibyte = blkid << dn->dn_datablkshift; + err = dnode_next_offset(dn, + DNODE_FIND_HAVELOCK, &ibyte, 2, 1, 0); + new_blkid = ibyte >> dn->dn_datablkshift; + if (err == ESRCH) { + skipped += (lastblk >> epbs) - (blkid >> epbs) + 1; + break; } - if (err && err != ENOENT) { + if (err) { txh->txh_tx->tx_err = err; break; } + if (new_blkid > lastblk) { + skipped += (lastblk >> epbs) - (blkid >> epbs) + 1; + break; + } + + if (new_blkid > blkid) { + ASSERT((new_blkid >> epbs) > (blkid >> epbs)); + skipped += (new_blkid >> epbs) - (blkid >> epbs) - 1; + nblks -= new_blkid - blkid; + blkid = new_blkid; + } + blkoff = P2PHASE(blkid, epb); + tochk = MIN(epb - blkoff, nblks); + + dbuf = dbuf_hold_level(dn, 1, blkid >> epbs, FTAG); + + txh->txh_memory_tohold += dbuf->db.db_size; + if (txh->txh_memory_tohold > DMU_MAX_ACCESS) { + txh->txh_tx->tx_err = E2BIG; + dbuf_rele(dbuf, FTAG); + break; + } + err = dbuf_read(dbuf, NULL, DB_RF_HAVESTRUCT | DB_RF_CANFAIL); + if (err != 0) { + txh->txh_tx->tx_err = err; + dbuf_rele(dbuf, FTAG); + break; + } + + bp = dbuf->db.db_data; + bp += blkoff; + + for (i = 0; i < tochk; i++) { + if (dsl_dataset_block_freeable(ds, bp[i].blk_birth)) { + dprintf_bp(&bp[i], "can free old%s", ""); + space += bp_get_dasize(spa, &bp[i]); + } + unref += BP_GET_ASIZE(bp); + } + dbuf_rele(dbuf, FTAG); blkid += tochk; nblks -= tochk; } rw_exit(&dn->dn_struct_rwlock); + /* account for new level 1 indirect blocks that might show up */ + if (skipped > 0) { + txh->txh_fudge += skipped << dn->dn_indblkshift; + skipped = MIN(skipped, DMU_MAX_DELETEBLKCNT >> epbs); + txh->txh_memory_tohold += skipped << dn->dn_indblkshift; + } txh->txh_space_tofree += space; txh->txh_space_tounref += unref; } @@ -471,7 +496,7 @@ dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len) /* * For i/o error checking, read the first and last level-0 * blocks, and all the level-1 blocks. The above count_write's - * will take care of the level-0 blocks. + * have already taken care of the level-0 blocks. */ if (dn->dn_nlevels > 1) { shift = dn->dn_datablkshift + dn->dn_indblkshift - @@ -483,7 +508,7 @@ dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len) NULL, NULL, ZIO_FLAG_CANFAIL); for (i = start; i <= end; i++) { uint64_t ibyte = i << shift; - err = dnode_next_offset(dn, FALSE, &ibyte, 2, 1, 0); + err = dnode_next_offset(dn, 0, &ibyte, 2, 1, 0); i = ibyte >> shift; if (err == ESRCH) break; @@ -583,7 +608,7 @@ dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, char *name) * 3 new blocks written if adding: new split leaf, 2 grown ptrtbl blocks */ dmu_tx_count_write(txh, dn->dn_maxblkid * dn->dn_datablksz, - (3 + add ? 3 : 0) << dn->dn_datablkshift); + (3 + (add ? 3 : 0)) << dn->dn_datablkshift); /* * If the modified blocks are scattered to the four winds, @@ -706,12 +731,13 @@ dmu_tx_dirty_buf(dmu_tx_t *tx, dmu_buf_impl_t *db) match_offset = TRUE; break; case THT_FREE: - if (blkid == beginblk && - (txh->txh_arg1 != 0 || - dn->dn_maxblkid == 0)) - match_offset = TRUE; - if (blkid == endblk && - txh->txh_arg2 != DMU_OBJECT_END) + /* + * We will dirty all the level 1 blocks in + * the free range and perhaps the first and + * last level 0 block. + */ + if (blkid >= beginblk && (blkid <= endblk || + txh->txh_arg2 == DMU_OBJECT_END)) match_offset = TRUE; break; case THT_BONUS: @@ -742,15 +768,15 @@ dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how) { dmu_tx_hold_t *txh; spa_t *spa = tx->tx_pool->dp_spa; - uint64_t lsize, asize, fsize, usize; - uint64_t towrite, tofree, tooverwrite, tounref; + uint64_t memory, asize, fsize, usize; + uint64_t towrite, tofree, tooverwrite, tounref, tohold, fudge; ASSERT3U(tx->tx_txg, ==, 0); if (tx->tx_err) return (tx->tx_err); - if (spa_state(spa) == POOL_STATE_IO_FAILURE) { + if (spa_suspended(spa)) { /* * If the user has indicated a blocking failure mode * then return ERESTART which will block in dmu_tx_wait(). @@ -776,7 +802,7 @@ dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how) * dmu_tx_unassign() logic. */ - towrite = tofree = tooverwrite = tounref = 0; + towrite = tofree = tooverwrite = tounref = tohold = fudge = 0; for (txh = list_head(&tx->tx_holds); txh; txh = list_next(&tx->tx_holds, txh)) { dnode_t *dn = txh->txh_dnode; @@ -797,6 +823,8 @@ dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how) tofree += txh->txh_space_tofree; tooverwrite += txh->txh_space_tooverwrite; tounref += txh->txh_space_tounref; + tohold += txh->txh_memory_tohold; + fudge += txh->txh_fudge; } /* @@ -817,24 +845,31 @@ dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how) tooverwrite = tofree = 0; } - /* - * Convert logical size to worst-case allocated size. - */ + /* needed allocation: worst-case estimate of write space */ + asize = spa_get_asize(tx->tx_pool->dp_spa, towrite + tooverwrite); + /* freed space estimate: worst-case overwrite + free estimate */ fsize = spa_get_asize(tx->tx_pool->dp_spa, tooverwrite) + tofree; - lsize = towrite + tooverwrite; - asize = spa_get_asize(tx->tx_pool->dp_spa, lsize); + /* convert unrefd space to worst-case estimate */ usize = spa_get_asize(tx->tx_pool->dp_spa, tounref); + /* calculate memory footprint estimate */ + memory = towrite + tooverwrite + tohold; #ifdef ZFS_DEBUG - tx->tx_space_towrite = asize; + /* + * Add in 'tohold' to account for our dirty holds on this memory + * XXX - the "fudge" factor is to account for skipped blocks that + * we missed because dnode_next_offset() misses in-core-only blocks. + */ + tx->tx_space_towrite = asize + + spa_get_asize(tx->tx_pool->dp_spa, tohold + fudge); tx->tx_space_tofree = tofree; tx->tx_space_tooverwrite = tooverwrite; tx->tx_space_tounref = tounref; #endif if (tx->tx_dir && asize != 0) { - int err = dsl_dir_tempreserve_space(tx->tx_dir, - lsize, asize, fsize, usize, &tx->tx_tempreserve_cookie, tx); + int err = dsl_dir_tempreserve_space(tx->tx_dir, memory, + asize, fsize, usize, &tx->tx_tempreserve_cookie, tx); if (err) return (err); } @@ -925,8 +960,7 @@ dmu_tx_wait(dmu_tx_t *tx) * has tried to obtain a tx. If that's the case then his * tx_lasttried_txg would not have been assigned. */ - if (spa_state(spa) == POOL_STATE_IO_FAILURE || - tx->tx_lasttried_txg == 0) { + if (spa_suspended(spa) || tx->tx_lasttried_txg == 0) { txg_wait_synced(tx->tx_pool, spa_last_synced_txg(spa) + 1); } else if (tx->tx_needassign_txh) { dnode_t *dn = tx->tx_needassign_txh->txh_dnode; diff --git a/zfs/lib/libzpool/dmu_zfetch.c b/zfs/lib/libzpool/dmu_zfetch.c index a47a0bcba..4d79fe98e 100644 --- a/zfs/lib/libzpool/dmu_zfetch.c +++ b/zfs/lib/libzpool/dmu_zfetch.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dmu_zfetch.c 1.6 06/10/26 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/dnode.c b/zfs/lib/libzpool/dnode.c index 3d40dc243..e77834d60 100644 --- a/zfs/lib/libzpool/dnode.c +++ b/zfs/lib/libzpool/dnode.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)dnode.c 1.20 07/08/26 SMI" - #include #include #include @@ -562,6 +560,12 @@ dnode_hold_impl(objset_impl_t *os, uint64_t object, int flag, dmu_buf_impl_t *db; dnode_t **children_dnodes; + /* + * If you are holding the spa config lock as writer, you shouldn't + * be asking the DMU to do *anything*. + */ + ASSERT(spa_config_held(os->os_spa, SCL_ALL, RW_WRITER) == 0); + if (object == 0 || object >= DN_MAX_OBJECT) return (EINVAL); @@ -780,7 +784,7 @@ int dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx) { dmu_buf_impl_t *db, *db_next; - int have_db0 = FALSE; + int err; if (size == 0) size = SPA_MINBLOCKSIZE; @@ -805,9 +809,7 @@ dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx) for (db = list_head(&dn->dn_dbufs); db; db = db_next) { db_next = list_next(&dn->dn_dbufs, db); - if (db->db_blkid == 0) { - have_db0 = TRUE; - } else if (db->db_blkid != DB_BONUS_BLKID) { + if (db->db_blkid != 0 && db->db_blkid != DB_BONUS_BLKID) { mutex_exit(&dn->dn_dbufs_mtx); goto fail; } @@ -817,12 +819,12 @@ dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx) if (ibs && dn->dn_nlevels != 1) goto fail; - db = NULL; - if (!BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) || have_db0) { - /* obtain the old block */ - db = dbuf_hold(dn, 0, FTAG); + /* resize the old block */ + err = dbuf_hold_impl(dn, 0, 0, TRUE, FTAG, &db); + if (err == 0) dbuf_new_size(db, size, tx); - } + else if (err != ENOENT) + goto fail; dnode_setdblksz(dn, size); dnode_setdirty(dn, tx); @@ -831,7 +833,7 @@ dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx) dn->dn_indblkshift = ibs; dn->dn_next_indblkshift[tx->tx_txg&TXG_MASK] = ibs; } - + /* rele after we have fixed the blocksize in the dnode */ if (db) dbuf_rele(db, FTAG); @@ -843,19 +845,32 @@ fail: return (ENOTSUP); } +/* read-holding callers must not rely on the lock being continuously held */ void -dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx) +dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx, boolean_t have_read) { uint64_t txgoff = tx->tx_txg & TXG_MASK; - int drop_struct_lock = FALSE; int epbs, new_nlevels; uint64_t sz; ASSERT(blkid != DB_BONUS_BLKID); - if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) { - rw_enter(&dn->dn_struct_rwlock, RW_WRITER); - drop_struct_lock = TRUE; + ASSERT(have_read ? + RW_READ_HELD(&dn->dn_struct_rwlock) : + RW_WRITE_HELD(&dn->dn_struct_rwlock)); + + /* + * if we have a read-lock, check to see if we need to do any work + * before upgrading to a write-lock. + */ + if (have_read) { + if (blkid <= dn->dn_maxblkid) + return; + + if (!rw_tryupgrade(&dn->dn_struct_rwlock)) { + rw_exit(&dn->dn_struct_rwlock); + rw_enter(&dn->dn_struct_rwlock, RW_WRITER); + } } if (blkid <= dn->dn_maxblkid) @@ -907,8 +922,8 @@ dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx) } out: - if (drop_struct_lock) - rw_exit(&dn->dn_struct_rwlock); + if (have_read) + rw_downgrade(&dn->dn_struct_rwlock); } void @@ -969,15 +984,15 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx) { dmu_buf_impl_t *db; uint64_t blkoff, blkid, nblks; - int blksz, head; + int blksz, blkshift, head, tail; int trunc = FALSE; + int epbs; rw_enter(&dn->dn_struct_rwlock, RW_WRITER); blksz = dn->dn_datablksz; + blkshift = dn->dn_datablkshift; + epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; - /* If the range is past the end of the file, this is a no-op */ - if (off >= blksz * (dn->dn_maxblkid+1)) - goto out; if (len == -1ULL) { len = UINT64_MAX - off; trunc = TRUE; @@ -989,11 +1004,18 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx) if (ISP2(blksz)) { head = P2NPHASE(off, blksz); blkoff = P2PHASE(off, blksz); + if ((off >> blkshift) > dn->dn_maxblkid) + goto out; } else { ASSERT(dn->dn_maxblkid == 0); if (off == 0 && len >= blksz) { - /* Freeing the whole block; don't do any head. */ - head = 0; + /* Freeing the whole block; fast-track this request */ + blkid = 0; + nblks = 1; + goto done; + } else if (off >= blksz) { + /* Freeing past end-of-data */ + goto out; } else { /* Freeing part of the block. */ head = blksz - off; @@ -1026,88 +1048,95 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx) } /* If the range was less than one block, we're done */ - if (len == 0 || off >= blksz * (dn->dn_maxblkid+1)) + if (len == 0) goto out; - if (!ISP2(blksz)) { - /* - * They are freeing the whole block of a - * non-power-of-two blocksize file. Skip all the messy - * math. - */ - ASSERT3U(off, ==, 0); - ASSERT3U(len, >=, blksz); - blkid = 0; - nblks = 1; - } else { - int tail; - int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; - int blkshift = dn->dn_datablkshift; + /* If the remaining range is past end of file, we're done */ + if ((off >> blkshift) > dn->dn_maxblkid) + goto out; - /* If the remaining range is past end of file, we're done */ - if (off > dn->dn_maxblkid << blkshift) - goto out; + ASSERT(ISP2(blksz)); + if (trunc) + tail = 0; + else + tail = P2PHASE(len, blksz); - if (off + len == UINT64_MAX) - tail = 0; - else - tail = P2PHASE(len, blksz); - - ASSERT3U(P2PHASE(off, blksz), ==, 0); - /* zero out any partial block data at the end of the range */ - if (tail) { - if (len < tail) - tail = len; - if (dbuf_hold_impl(dn, 0, dbuf_whichblock(dn, off+len), - TRUE, FTAG, &db) == 0) { - /* don't dirty if not on disk and not dirty */ - if (db->db_last_dirty || - (db->db_blkptr && - !BP_IS_HOLE(db->db_blkptr))) { - rw_exit(&dn->dn_struct_rwlock); - dbuf_will_dirty(db, tx); - rw_enter(&dn->dn_struct_rwlock, - RW_WRITER); - bzero(db->db.db_data, tail); - } - dbuf_rele(db, FTAG); + ASSERT3U(P2PHASE(off, blksz), ==, 0); + /* zero out any partial block data at the end of the range */ + if (tail) { + if (len < tail) + tail = len; + if (dbuf_hold_impl(dn, 0, dbuf_whichblock(dn, off+len), + TRUE, FTAG, &db) == 0) { + /* don't dirty if not on disk and not dirty */ + if (db->db_last_dirty || + (db->db_blkptr && !BP_IS_HOLE(db->db_blkptr))) { + rw_exit(&dn->dn_struct_rwlock); + dbuf_will_dirty(db, tx); + rw_enter(&dn->dn_struct_rwlock, RW_WRITER); + bzero(db->db.db_data, tail); } - len -= tail; - } - /* If the range did not include a full block, we are done */ - if (len == 0) - goto out; - - /* dirty the left indirects */ - if (dn->dn_nlevels > 1 && off != 0) { - db = dbuf_hold_level(dn, 1, - (off - head) >> (blkshift + epbs), FTAG); - dbuf_will_dirty(db, tx); dbuf_rele(db, FTAG); } - - /* dirty the right indirects */ - if (dn->dn_nlevels > 1 && !trunc) { - db = dbuf_hold_level(dn, 1, - (off + len + tail - 1) >> (blkshift + epbs), FTAG); - dbuf_will_dirty(db, tx); - dbuf_rele(db, FTAG); - } - - /* - * Finally, add this range to the dnode range list, we - * will finish up this free operation in the syncing phase. - */ - ASSERT(IS_P2ALIGNED(off, 1<> blkshift; - nblks = len >> blkshift; - - if (trunc) - dn->dn_maxblkid = (blkid ? blkid - 1 : 0); + len -= tail; } + /* If the range did not include a full block, we are done */ + if (len == 0) + goto out; + + ASSERT(IS_P2ALIGNED(off, blksz)); + ASSERT(trunc || IS_P2ALIGNED(len, blksz)); + blkid = off >> blkshift; + nblks = len >> blkshift; + if (trunc) + nblks += 1; + + /* + * Read in and mark all the level-1 indirects dirty, + * so that they will stay in memory until syncing phase. + * Always dirty the first and last indirect to make sure + * we dirty all the partial indirects. + */ + if (dn->dn_nlevels > 1) { + uint64_t i, first, last; + int shift = epbs + dn->dn_datablkshift; + + first = blkid >> epbs; + if (db = dbuf_hold_level(dn, 1, first, FTAG)) { + dbuf_will_dirty(db, tx); + dbuf_rele(db, FTAG); + } + if (trunc) + last = dn->dn_maxblkid >> epbs; + else + last = (blkid + nblks - 1) >> epbs; + if (last > first && (db = dbuf_hold_level(dn, 1, last, FTAG))) { + dbuf_will_dirty(db, tx); + dbuf_rele(db, FTAG); + } + for (i = first + 1; i < last; i++) { + uint64_t ibyte = i << shift; + int err; + + err = dnode_next_offset(dn, + DNODE_FIND_HAVELOCK, &ibyte, 1, 1, 0); + i = ibyte >> shift; + if (err == ESRCH || i >= last) + break; + ASSERT(err == 0); + db = dbuf_hold_level(dn, 1, i, FTAG); + if (db) { + dbuf_will_dirty(db, tx); + dbuf_rele(db, FTAG); + } + } + } +done: + /* + * Add this range to the dnode range list. + * We will finish up this free operation in the syncing phase. + */ mutex_enter(&dn->dn_mtx); dnode_clear_range(dn, blkid, nblks, tx); { @@ -1127,9 +1156,12 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx) } mutex_exit(&dn->dn_mtx); - dbuf_free_range(dn, blkid, nblks, tx); + dbuf_free_range(dn, blkid, blkid + nblks - 1, tx); dnode_setdirty(dn, tx); out: + if (trunc && dn->dn_maxblkid >= (off >> blkshift)) + dn->dn_maxblkid = (off >> blkshift ? (off >> blkshift) - 1 : 0); + rw_exit(&dn->dn_struct_rwlock); } @@ -1229,7 +1261,7 @@ dnode_willuse_space(dnode_t *dn, int64_t space, dmu_tx_t *tx) } static int -dnode_next_offset_level(dnode_t *dn, boolean_t hole, uint64_t *offset, +dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset, int lvl, uint64_t blkfill, uint64_t txg) { dmu_buf_impl_t *db = NULL; @@ -1237,11 +1269,16 @@ dnode_next_offset_level(dnode_t *dn, boolean_t hole, uint64_t *offset, uint64_t epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT; uint64_t epb = 1ULL << epbs; uint64_t minfill, maxfill; - int i, error, span; + boolean_t hole; + int i, inc, error, span; dprintf("probing object %llu offset %llx level %d of %u\n", dn->dn_object, *offset, lvl, dn->dn_phys->dn_nlevels); + hole = flags & DNODE_FIND_HOLE; + inc = (flags & DNODE_FIND_BACKWARDS) ? -1 : 1; + ASSERT(txg == 0 || !hole); + if (lvl == dn->dn_phys->dn_nlevels) { error = 0; epb = dn->dn_phys->dn_nblkptr; @@ -1250,9 +1287,18 @@ dnode_next_offset_level(dnode_t *dn, boolean_t hole, uint64_t *offset, uint64_t blkid = dbuf_whichblock(dn, *offset) >> (epbs * lvl); error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FTAG, &db); if (error) { - if (error == ENOENT) - return (hole ? 0 : ESRCH); - return (error); + if (error != ENOENT) + return (error); + if (hole) + return (0); + /* + * This can only happen when we are searching up + * the block tree for data. We don't really need to + * adjust the offset, as we will just end up looking + * at the pointer to this block in its parent, and its + * going to be unallocated, so we will skip over it. + */ + return (ESRCH); } error = dbuf_read(db, NULL, DB_RF_CANFAIL | DB_RF_HAVESTRUCT); if (error) { @@ -1264,13 +1310,18 @@ dnode_next_offset_level(dnode_t *dn, boolean_t hole, uint64_t *offset, if (db && txg && (db->db_blkptr == NULL || db->db_blkptr->blk_birth <= txg)) { + /* + * This can only happen when we are searching up the tree + * and these conditions mean that we need to keep climbing. + */ error = ESRCH; } else if (lvl == 0) { dnode_phys_t *dnp = data; span = DNODE_SHIFT; ASSERT(dn->dn_type == DMU_OT_DNODE); - for (i = (*offset >> span) & (blkfill - 1); i < blkfill; i++) { + for (i = (*offset >> span) & (blkfill - 1); + i >= 0 && i < blkfill; i += inc) { boolean_t newcontents = B_TRUE; if (txg) { int j; @@ -1282,9 +1333,9 @@ dnode_next_offset_level(dnode_t *dn, boolean_t hole, uint64_t *offset, } if (!dnp[i].dn_type == hole && newcontents) break; - *offset += 1ULL << span; + *offset += (1ULL << span) * inc; } - if (i == blkfill) + if (i < 0 || i == blkfill) error = ESRCH; } else { blkptr_t *bp = data; @@ -1298,14 +1349,17 @@ dnode_next_offset_level(dnode_t *dn, boolean_t hole, uint64_t *offset, minfill++; for (i = (*offset >> span) & ((1ULL << epbs) - 1); - i < epb; i++) { + i >= 0 && i < epb; i += inc) { if (bp[i].blk_fill >= minfill && bp[i].blk_fill <= maxfill && - bp[i].blk_birth > txg) + (hole || bp[i].blk_birth > txg)) break; - *offset += 1ULL << span; + if (inc < 0 && *offset < (1ULL << span)) + *offset = 0; + else + *offset += (1ULL << span) * inc; } - if (i >= epb) + if (i < 0 || i == epb) error = ESRCH; } @@ -1324,64 +1378,66 @@ dnode_next_offset_level(dnode_t *dn, boolean_t hole, uint64_t *offset, * * Examples: * - * dnode_next_offset(dn, hole, offset, 1, 1, 0); - * Finds the next hole/data in a file. + * dnode_next_offset(dn, flags, offset, 1, 1, 0); + * Finds the next/previous hole/data in a file. * Used in dmu_offset_next(). * - * dnode_next_offset(mdn, hole, offset, 0, DNODES_PER_BLOCK, txg); + * dnode_next_offset(mdn, flags, offset, 0, DNODES_PER_BLOCK, txg); * Finds the next free/allocated dnode an objset's meta-dnode. * Only finds objects that have new contents since txg (ie. * bonus buffer changes and content removal are ignored). * Used in dmu_object_next(). * - * dnode_next_offset(mdn, TRUE, offset, 2, DNODES_PER_BLOCK >> 2, 0); + * dnode_next_offset(mdn, DNODE_FIND_HOLE, offset, 2, DNODES_PER_BLOCK >> 2, 0); * Finds the next L2 meta-dnode bp that's at most 1/4 full. * Used in dmu_object_alloc(). */ int -dnode_next_offset(dnode_t *dn, boolean_t hole, uint64_t *offset, +dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset, int minlvl, uint64_t blkfill, uint64_t txg) { + uint64_t initial_offset = *offset; int lvl, maxlvl; int error = 0; - uint64_t initial_offset = *offset; - rw_enter(&dn->dn_struct_rwlock, RW_READER); + if (!(flags & DNODE_FIND_HAVELOCK)) + rw_enter(&dn->dn_struct_rwlock, RW_READER); if (dn->dn_phys->dn_nlevels == 0) { - rw_exit(&dn->dn_struct_rwlock); - return (ESRCH); + error = ESRCH; + goto out; } if (dn->dn_datablkshift == 0) { if (*offset < dn->dn_datablksz) { - if (hole) + if (flags & DNODE_FIND_HOLE) *offset = dn->dn_datablksz; } else { error = ESRCH; } - rw_exit(&dn->dn_struct_rwlock); - return (error); + goto out; } maxlvl = dn->dn_phys->dn_nlevels; for (lvl = minlvl; lvl <= maxlvl; lvl++) { error = dnode_next_offset_level(dn, - hole, offset, lvl, blkfill, txg); + flags, offset, lvl, blkfill, txg); if (error != ESRCH) break; } - while (--lvl >= minlvl && error == 0) { + while (error == 0 && --lvl >= minlvl) { error = dnode_next_offset_level(dn, - hole, offset, lvl, blkfill, txg); + flags, offset, lvl, blkfill, txg); } - rw_exit(&dn->dn_struct_rwlock); - - if (error == 0 && initial_offset > *offset) + if (error == 0 && (flags & DNODE_FIND_BACKWARDS ? + initial_offset < *offset : initial_offset > *offset)) error = ESRCH; +out: + if (!(flags & DNODE_FIND_HAVELOCK)) + rw_exit(&dn->dn_struct_rwlock); return (error); } diff --git a/zfs/lib/libzpool/dnode_sync.c b/zfs/lib/libzpool/dnode_sync.c index 0fdd27ecf..779cfc96f 100644 --- a/zfs/lib/libzpool/dnode_sync.c +++ b/zfs/lib/libzpool/dnode_sync.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)dnode_sync.c 1.19 07/08/26 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -109,25 +109,26 @@ dnode_increase_indirection(dnode_t *dn, dmu_tx_t *tx) rw_exit(&dn->dn_struct_rwlock); } -static void +static int free_blocks(dnode_t *dn, blkptr_t *bp, int num, dmu_tx_t *tx) { - objset_impl_t *os = dn->dn_objset; + dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; uint64_t bytesfreed = 0; - int i; + int i, blocks_freed = 0; - dprintf("os=%p obj=%llx num=%d\n", os, dn->dn_object, num); + dprintf("ds=%p obj=%llx num=%d\n", ds, dn->dn_object, num); for (i = 0; i < num; i++, bp++) { if (BP_IS_HOLE(bp)) continue; - bytesfreed += bp_get_dasize(os->os_spa, bp); + bytesfreed += dsl_dataset_block_kill(ds, bp, dn->dn_zio, tx); ASSERT3U(bytesfreed, <=, DN_USED_BYTES(dn->dn_phys)); - dsl_dataset_block_kill(os->os_dsl_dataset, bp, dn->dn_zio, tx); bzero(bp, sizeof (blkptr_t)); + blocks_freed += 1; } dnode_diduse_space(dn, -bytesfreed); + return (blocks_freed); } #ifdef ZFS_DEBUG @@ -177,7 +178,7 @@ free_verify(dmu_buf_impl_t *db, uint64_t start, uint64_t end, dmu_tx_t *tx) if (buf[j] != 0) { panic("freed data not zero: " "child=%p i=%d off=%d num=%d\n", - child, i, off, num); + (void *)child, i, off, num); } } } @@ -194,7 +195,7 @@ free_verify(dmu_buf_impl_t *db, uint64_t start, uint64_t end, dmu_tx_t *tx) if (buf[j] != 0) { panic("freed data not zero: " "child=%p i=%d off=%d num=%d\n", - child, i, off, num); + (void *)child, i, off, num); } } } @@ -205,6 +206,8 @@ free_verify(dmu_buf_impl_t *db, uint64_t start, uint64_t end, dmu_tx_t *tx) } #endif +#define ALL -1 + static int free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks, int trunc, dmu_tx_t *tx) @@ -215,8 +218,18 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks, int trunc, uint64_t start, end, dbstart, dbend, i; int epbs, shift, err; int all = TRUE; + int blocks_freed = 0; + + /* + * There is a small possibility that this block will not be cached: + * 1 - if level > 1 and there are no children with level <= 1 + * 2 - if we didn't get a dirty hold (because this block had just + * finished being written -- and so had no holds), and then this + * block got evicted before we got here. + */ + if (db->db_state != DB_CACHED) + (void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED); - (void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED); arc_release(db->db_buf, db); bp = (blkptr_t *)db->db.db_data; @@ -240,10 +253,10 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks, int trunc, if (db->db_level == 1) { FREE_VERIFY(db, start, end, tx); - free_blocks(dn, bp, end-start+1, tx); + blocks_freed = free_blocks(dn, bp, end-start+1, tx); arc_buf_freeze(db->db_buf); - ASSERT(all || db->db_last_dirty); - return (all); + ASSERT(all || blocks_freed == 0 || db->db_last_dirty); + return (all ? ALL : blocks_freed); } for (i = start; i <= end; i++, bp++) { @@ -254,9 +267,9 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks, int trunc, ASSERT3U(err, ==, 0); rw_exit(&dn->dn_struct_rwlock); - if (free_children(subdb, blkid, nblks, trunc, tx)) { + if (free_children(subdb, blkid, nblks, trunc, tx) == ALL) { ASSERT3P(subdb->db_blkptr, ==, bp); - free_blocks(dn, bp, 1, tx); + blocks_freed += free_blocks(dn, bp, 1, tx); } else { all = FALSE; } @@ -273,8 +286,8 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks, int trunc, ASSERT3U(bp->blk_birth, ==, 0); } #endif - ASSERT(all || db->db_last_dirty); - return (all); + ASSERT(all || blocks_freed == 0 || db->db_last_dirty); + return (all ? ALL : blocks_freed); } /* @@ -304,15 +317,14 @@ dnode_sync_free_range(dnode_t *dn, uint64_t blkid, uint64_t nblks, dmu_tx_t *tx) return; } ASSERT3U(blkid + nblks, <=, dn->dn_phys->dn_nblkptr); - free_blocks(dn, bp + blkid, nblks, tx); + (void) free_blocks(dn, bp + blkid, nblks, tx); if (trunc) { uint64_t off = (dn->dn_phys->dn_maxblkid + 1) * (dn->dn_phys->dn_datablkszsec << SPA_MINBLOCKSHIFT); dn->dn_phys->dn_maxblkid = (blkid ? blkid - 1 : 0); ASSERT(off < dn->dn_phys->dn_maxblkid || dn->dn_phys->dn_maxblkid == 0 || - dnode_next_offset(dn, FALSE, &off, - 1, 1, 0) != 0); + dnode_next_offset(dn, 0, &off, 1, 1, 0) != 0); } return; } @@ -330,9 +342,9 @@ dnode_sync_free_range(dnode_t *dn, uint64_t blkid, uint64_t nblks, dmu_tx_t *tx) ASSERT3U(err, ==, 0); rw_exit(&dn->dn_struct_rwlock); - if (free_children(db, blkid, nblks, trunc, tx)) { + if (free_children(db, blkid, nblks, trunc, tx) == ALL) { ASSERT3P(db->db_blkptr, ==, bp); - free_blocks(dn, bp, 1, tx); + (void) free_blocks(dn, bp, 1, tx); } dbuf_rele(db, FTAG); } @@ -342,7 +354,7 @@ dnode_sync_free_range(dnode_t *dn, uint64_t blkid, uint64_t nblks, dmu_tx_t *tx) dn->dn_phys->dn_maxblkid = (blkid ? blkid - 1 : 0); ASSERT(off < dn->dn_phys->dn_maxblkid || dn->dn_phys->dn_maxblkid == 0 || - dnode_next_offset(dn, FALSE, &off, 1, 1, 0) != 0); + dnode_next_offset(dn, 0, &off, 1, 1, 0) != 0); } } @@ -375,7 +387,6 @@ dnode_evict_dbufs(dnode_t *dn) mutex_exit(&db->db_mtx); } else if (refcount_is_zero(&db->db_holds)) { progress = TRUE; - ASSERT(!arc_released(db->db_buf)); dbuf_clear(db); /* exits db_mtx for us */ } else { mutex_exit(&db->db_mtx); @@ -442,6 +453,13 @@ dnode_sync_free(dnode_t *dn, dmu_tx_t *tx) ASSERT(dmu_tx_is_syncing(tx)); + /* + * Our contents should have been freed in dnode_sync() by the + * free range record inserted by the caller of dnode_free(). + */ + ASSERT3U(DN_USED_BYTES(dn->dn_phys), ==, 0); + ASSERT(BP_IS_HOLE(dn->dn_phys->dn_blkptr)); + dnode_undirty_dbufs(&dn->dn_dirty_records[txgoff]); dnode_evict_dbufs(dn); ASSERT3P(list_head(&dn->dn_dbufs), ==, NULL); @@ -461,10 +479,6 @@ dnode_sync_free(dnode_t *dn, dmu_tx_t *tx) dn->dn_next_indblkshift[txgoff] = 0; dn->dn_next_blksz[txgoff] = 0; - /* free up all the blocks in the file. */ - dnode_sync_free_range(dn, 0, dn->dn_phys->dn_maxblkid+1, tx); - ASSERT3U(DN_USED_BYTES(dn->dn_phys), ==, 0); - /* ASSERT(blkptrs are zero); */ ASSERT(dn->dn_phys->dn_type != DMU_OT_NONE); ASSERT(dn->dn_type != DMU_OT_NONE); @@ -541,7 +555,7 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx) ASSERT(P2PHASE(dn->dn_next_blksz[txgoff], SPA_MINBLOCKSIZE) == 0); ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[0]) || - list_head(list) != NULL || + dn->dn_maxblkid == 0 || list_head(list) != NULL || dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT == dnp->dn_datablkszsec); dnp->dn_datablkszsec = @@ -575,22 +589,15 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx) mutex_exit(&dn->dn_mtx); /* process all the "freed" ranges in the file */ - if (dn->dn_free_txg == 0 || dn->dn_free_txg > tx->tx_txg) { - for (rp = avl_last(&dn->dn_ranges[txgoff]); rp != NULL; - rp = AVL_PREV(&dn->dn_ranges[txgoff], rp)) - dnode_sync_free_range(dn, - rp->fr_blkid, rp->fr_nblks, tx); + while (rp = avl_last(&dn->dn_ranges[txgoff])) { + dnode_sync_free_range(dn, rp->fr_blkid, rp->fr_nblks, tx); + /* grab the mutex so we don't race with dnode_block_freed() */ + mutex_enter(&dn->dn_mtx); + avl_remove(&dn->dn_ranges[txgoff], rp); + mutex_exit(&dn->dn_mtx); + kmem_free(rp, sizeof (free_range_t)); } - /* grab the mutex so we don't race with dnode_block_freed() */ - mutex_enter(&dn->dn_mtx); - for (rp = avl_first(&dn->dn_ranges[txgoff]); rp; ) { - free_range_t *last = rp; - rp = AVL_NEXT(&dn->dn_ranges[txgoff], rp); - avl_remove(&dn->dn_ranges[txgoff], last); - kmem_free(last, sizeof (free_range_t)); - } - mutex_exit(&dn->dn_mtx); if (dn->dn_free_txg > 0 && dn->dn_free_txg <= tx->tx_txg) { dnode_sync_free(dn, tx); return; diff --git a/zfs/lib/libzpool/dsl_dataset.c b/zfs/lib/libzpool/dsl_dataset.c index 88a280d67..93ea8aa11 100644 --- a/zfs/lib/libzpool/dsl_dataset.c +++ b/zfs/lib/libzpool/dsl_dataset.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dsl_dataset.c 1.42 08/04/28 SMI" - #include #include #include @@ -39,8 +37,11 @@ #include #include #include +#include #include +static char *dsl_reaper = "the grim reaper"; + static dsl_checkfunc_t dsl_dataset_destroy_begin_check; static dsl_syncfunc_t dsl_dataset_destroy_begin_sync; static dsl_checkfunc_t dsl_dataset_rollback_check; @@ -51,22 +52,8 @@ static dsl_syncfunc_t dsl_dataset_set_reservation_sync; #define DSL_DEADLIST_BLOCKSIZE SPA_MAXBLOCKSIZE -/* - * We use weighted reference counts to express the various forms of exclusion - * between different open modes. A STANDARD open is 1 point, an EXCLUSIVE open - * is DS_REF_MAX, and a PRIMARY open is little more than half of an EXCLUSIVE. - * This makes the exclusion logic simple: the total refcnt for all opens cannot - * exceed DS_REF_MAX. For example, EXCLUSIVE opens are exclusive because their - * weight (DS_REF_MAX) consumes the entire refcnt space. PRIMARY opens consume - * just over half of the refcnt space, so there can't be more than one, but it - * can peacefully coexist with any number of STANDARD opens. - */ -static uint64_t ds_refcnt_weight[DS_MODE_LEVELS] = { - 0, /* DS_MODE_NONE - invalid */ - 1, /* DS_MODE_STANDARD - unlimited number */ - (DS_REF_MAX >> 1) + 1, /* DS_MODE_PRIMARY - only one of these */ - DS_REF_MAX /* DS_MODE_EXCLUSIVE - no other opens */ -}; +#define DSL_DATASET_IS_DESTROYED(ds) ((ds)->ds_owner == dsl_reaper) + /* * Figure out how much of this delta should be propogated to the dsl_dir @@ -110,12 +97,13 @@ dsl_dataset_block_born(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx) * dsl_dir. */ ASSERT3U(compressed, ==, uncompressed); /* it's all metadata */ - dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, + dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, DD_USED_HEAD, used, compressed, uncompressed, tx); dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx); return; } dmu_buf_will_dirty(ds->ds_dbuf, tx); + mutex_enter(&ds->ds_dir->dd_lock); mutex_enter(&ds->ds_lock); delta = parent_delta(ds, used); ds->ds_phys->ds_used_bytes += used; @@ -123,10 +111,14 @@ dsl_dataset_block_born(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx) ds->ds_phys->ds_uncompressed_bytes += uncompressed; ds->ds_phys->ds_unique_bytes += used; mutex_exit(&ds->ds_lock); - dsl_dir_diduse_space(ds->ds_dir, delta, compressed, uncompressed, tx); + dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta, + compressed, uncompressed, tx); + dsl_dir_transfer_space(ds->ds_dir, used - delta, + DD_USED_REFRSRV, DD_USED_HEAD, tx); + mutex_exit(&ds->ds_dir->dd_lock); } -void +int dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, dmu_tx_t *tx) { @@ -134,10 +126,11 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, int compressed = BP_GET_PSIZE(bp); int uncompressed = BP_GET_UCSIZE(bp); + ASSERT(pio != NULL); ASSERT(dmu_tx_is_syncing(tx)); /* No block pointer => nothing to free */ if (BP_IS_HOLE(bp)) - return; + return (0); ASSERT(used > 0); if (ds == NULL) { @@ -146,17 +139,18 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, * Account for the meta-objset space in its placeholder * dataset. */ - err = arc_free(pio, tx->tx_pool->dp_spa, - tx->tx_txg, bp, NULL, NULL, pio ? ARC_NOWAIT: ARC_WAIT); + err = dsl_free(pio, tx->tx_pool, + tx->tx_txg, bp, NULL, NULL, ARC_NOWAIT); ASSERT(err == 0); - dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, + dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, DD_USED_HEAD, -used, -compressed, -uncompressed, tx); dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx); - return; + return (used); } ASSERT3P(tx->tx_pool, ==, ds->ds_dir->dd_pool); + ASSERT(!dsl_dataset_is_snapshot(ds)); dmu_buf_will_dirty(ds->ds_dbuf, tx); if (bp->blk_birth > ds->ds_phys->ds_prev_snap_txg) { @@ -164,18 +158,22 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, int64_t delta; dprintf_bp(bp, "freeing: %s", ""); - err = arc_free(pio, tx->tx_pool->dp_spa, - tx->tx_txg, bp, NULL, NULL, pio ? ARC_NOWAIT: ARC_WAIT); + err = dsl_free(pio, tx->tx_pool, + tx->tx_txg, bp, NULL, NULL, ARC_NOWAIT); ASSERT(err == 0); + mutex_enter(&ds->ds_dir->dd_lock); mutex_enter(&ds->ds_lock); ASSERT(ds->ds_phys->ds_unique_bytes >= used || !DS_UNIQUE_IS_ACCURATE(ds)); delta = parent_delta(ds, -used); ds->ds_phys->ds_unique_bytes -= used; mutex_exit(&ds->ds_lock); - dsl_dir_diduse_space(ds->ds_dir, + dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta, -compressed, -uncompressed, tx); + dsl_dir_transfer_space(ds->ds_dir, -used - delta, + DD_USED_REFRSRV, DD_USED_HEAD, tx); + mutex_exit(&ds->ds_dir->dd_lock); } else { dprintf_bp(bp, "putting on dead list: %s", ""); VERIFY(0 == bplist_enqueue(&ds->ds_deadlist, bp, tx)); @@ -191,6 +189,10 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, ds->ds_prev->ds_phys->ds_unique_bytes += used; mutex_exit(&ds->ds_prev->ds_lock); } + if (bp->blk_birth > ds->ds_origin_txg) { + dsl_dir_transfer_space(ds->ds_dir, used, + DD_USED_HEAD, DD_USED_SNAP, tx); + } } mutex_enter(&ds->ds_lock); ASSERT3U(ds->ds_phys->ds_used_bytes, >=, used); @@ -200,6 +202,8 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, ASSERT3U(ds->ds_phys->ds_uncompressed_bytes, >=, uncompressed); ds->ds_phys->ds_uncompressed_bytes -= uncompressed; mutex_exit(&ds->ds_lock); + + return (used); } uint64_t @@ -237,9 +241,7 @@ dsl_dataset_evict(dmu_buf_t *db, void *dsv) { dsl_dataset_t *ds = dsv; - /* open_refcount == DS_REF_MAX when deleting */ - ASSERT(ds->ds_open_refcount == 0 || - ds->ds_open_refcount == DS_REF_MAX); + ASSERT(ds->ds_owner == NULL || DSL_DATASET_IS_DESTROYED(ds)); dprintf_ds(ds, "evicting %s\n", ""); @@ -249,18 +251,21 @@ dsl_dataset_evict(dmu_buf_t *db, void *dsv) ds->ds_user_evict_func(ds, ds->ds_user_ptr); if (ds->ds_prev) { - dsl_dataset_close(ds->ds_prev, DS_MODE_NONE, ds); + dsl_dataset_drop_ref(ds->ds_prev, ds); ds->ds_prev = NULL; } bplist_close(&ds->ds_deadlist); - dsl_dir_close(ds->ds_dir, ds); + if (ds->ds_dir) + dsl_dir_close(ds->ds_dir, ds); ASSERT(!list_link_active(&ds->ds_synced_link)); mutex_destroy(&ds->ds_lock); mutex_destroy(&ds->ds_opening_lock); mutex_destroy(&ds->ds_deadlist.bpl_lock); + rw_destroy(&ds->ds_rwlock); + cv_destroy(&ds->ds_exclusive_cv); kmem_free(ds, sizeof (dsl_dataset_t)); } @@ -291,47 +296,48 @@ dsl_dataset_get_snapname(dsl_dataset_t *ds) } static int -dsl_dataset_snap_lookup(objset_t *os, uint64_t flags, - uint64_t snapnames_zapobj, const char *name, uint64_t *value) +dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name, uint64_t *value) { + objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; + uint64_t snapobj = ds->ds_phys->ds_snapnames_zapobj; matchtype_t mt; int err; - if (flags & DS_FLAG_CI_DATASET) + if (ds->ds_phys->ds_flags & DS_FLAG_CI_DATASET) mt = MT_FIRST; else mt = MT_EXACT; - err = zap_lookup_norm(os, snapnames_zapobj, name, 8, 1, + err = zap_lookup_norm(mos, snapobj, name, 8, 1, value, mt, NULL, 0, NULL); if (err == ENOTSUP && mt == MT_FIRST) - err = zap_lookup(os, snapnames_zapobj, name, 8, 1, value); + err = zap_lookup(mos, snapobj, name, 8, 1, value); return (err); } static int -dsl_dataset_snap_remove(objset_t *os, uint64_t flags, - uint64_t snapnames_zapobj, char *name, dmu_tx_t *tx) +dsl_dataset_snap_remove(dsl_dataset_t *ds, char *name, dmu_tx_t *tx) { + objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; + uint64_t snapobj = ds->ds_phys->ds_snapnames_zapobj; matchtype_t mt; int err; - if (flags & DS_FLAG_CI_DATASET) + if (ds->ds_phys->ds_flags & DS_FLAG_CI_DATASET) mt = MT_FIRST; else mt = MT_EXACT; - err = zap_remove_norm(os, snapnames_zapobj, name, mt, tx); + err = zap_remove_norm(mos, snapobj, name, mt, tx); if (err == ENOTSUP && mt == MT_FIRST) - err = zap_remove(os, snapnames_zapobj, name, tx); + err = zap_remove(mos, snapobj, name, tx); return (err); } -int -dsl_dataset_open_obj(dsl_pool_t *dp, uint64_t dsobj, const char *snapname, - int mode, void *tag, dsl_dataset_t **dsp) +static int +dsl_dataset_get_ref(dsl_pool_t *dp, uint64_t dsobj, void *tag, + dsl_dataset_t **dsp) { - uint64_t weight = ds_refcnt_weight[DS_MODE_LEVEL(mode)]; objset_t *mos = dp->dp_meta_objset; dmu_buf_t *dbuf; dsl_dataset_t *ds; @@ -356,6 +362,8 @@ dsl_dataset_open_obj(dsl_pool_t *dp, uint64_t dsobj, const char *snapname, mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&ds->ds_deadlist.bpl_lock, NULL, MUTEX_DEFAULT, NULL); + rw_init(&ds->ds_rwlock, 0, 0, 0); + cv_init(&ds->ds_exclusive_cv, NULL, CV_DEFAULT, NULL); err = bplist_open(&ds->ds_deadlist, mos, ds->ds_phys->ds_deadlist_obj); @@ -371,46 +379,38 @@ dsl_dataset_open_obj(dsl_pool_t *dp, uint64_t dsobj, const char *snapname, mutex_destroy(&ds->ds_lock); mutex_destroy(&ds->ds_opening_lock); mutex_destroy(&ds->ds_deadlist.bpl_lock); + rw_destroy(&ds->ds_rwlock); + cv_destroy(&ds->ds_exclusive_cv); kmem_free(ds, sizeof (dsl_dataset_t)); dmu_buf_rele(dbuf, tag); return (err); } - if (ds->ds_dir->dd_phys->dd_head_dataset_obj == dsobj) { + if (!dsl_dataset_is_snapshot(ds)) { ds->ds_snapname[0] = '\0'; if (ds->ds_phys->ds_prev_snap_obj) { - err = dsl_dataset_open_obj(dp, - ds->ds_phys->ds_prev_snap_obj, NULL, - DS_MODE_NONE, ds, &ds->ds_prev); + err = dsl_dataset_get_ref(dp, + ds->ds_phys->ds_prev_snap_obj, + ds, &ds->ds_prev); } - } else { - if (snapname) { -#ifdef ZFS_DEBUG - dsl_dataset_phys_t *headphys; - dmu_buf_t *headdbuf; - err = dmu_bonus_hold(mos, - ds->ds_dir->dd_phys->dd_head_dataset_obj, - FTAG, &headdbuf); - if (err == 0) { - uint64_t foundobj; - headphys = headdbuf->db_data; - err = dsl_dataset_snap_lookup( - dp->dp_meta_objset, - headphys->ds_flags, - headphys->ds_snapnames_zapobj, - snapname, &foundobj); - ASSERT3U(foundobj, ==, dsobj); - dmu_buf_rele(headdbuf, FTAG); + if (err == 0 && dsl_dir_is_clone(ds->ds_dir)) { + dsl_dataset_t *origin; + + err = dsl_dataset_hold_obj(dp, + ds->ds_dir->dd_phys->dd_origin_obj, + FTAG, &origin); + if (err == 0) { + ds->ds_origin_txg = + origin->ds_phys->ds_creation_txg; + dsl_dataset_rele(origin, FTAG); } -#endif - (void) strcat(ds->ds_snapname, snapname); - } else if (zfs_flags & ZFS_DEBUG_SNAPNAMES) { - err = dsl_dataset_get_snapname(ds); } + } else if (zfs_flags & ZFS_DEBUG_SNAPNAMES) { + err = dsl_dataset_get_snapname(ds); } - if (!dsl_dataset_is_snapshot(ds)) { + if (err == 0 && !dsl_dataset_is_snapshot(ds)) { /* * In sync context, we're called with either no lock * or with the write lock. If we're not syncing, @@ -423,11 +423,11 @@ dsl_dataset_open_obj(dsl_pool_t *dp, uint64_t dsobj, const char *snapname, if (need_lock) rw_enter(&dp->dp_config_rwlock, RW_READER); - err = dsl_prop_get_ds_locked(ds->ds_dir, + err = dsl_prop_get_ds(ds, "refreservation", sizeof (uint64_t), 1, &ds->ds_reserved, NULL); if (err == 0) { - err = dsl_prop_get_ds_locked(ds->ds_dir, + err = dsl_prop_get_ds(ds, "refquota", sizeof (uint64_t), 1, &ds->ds_quota, NULL); } @@ -444,14 +444,14 @@ dsl_dataset_open_obj(dsl_pool_t *dp, uint64_t dsobj, const char *snapname, } if (err || winner) { bplist_close(&ds->ds_deadlist); - if (ds->ds_prev) { - dsl_dataset_close(ds->ds_prev, - DS_MODE_NONE, ds); - } + if (ds->ds_prev) + dsl_dataset_drop_ref(ds->ds_prev, ds); dsl_dir_close(ds->ds_dir, ds); mutex_destroy(&ds->ds_lock); mutex_destroy(&ds->ds_opening_lock); mutex_destroy(&ds->ds_deadlist.bpl_lock); + rw_destroy(&ds->ds_rwlock); + cv_destroy(&ds->ds_exclusive_cv); kmem_free(ds, sizeof (dsl_dataset_t)); if (err) { dmu_buf_rele(dbuf, tag); @@ -465,93 +465,169 @@ dsl_dataset_open_obj(dsl_pool_t *dp, uint64_t dsobj, const char *snapname, } ASSERT3P(ds->ds_dbuf, ==, dbuf); ASSERT3P(ds->ds_phys, ==, dbuf->db_data); - + ASSERT(ds->ds_phys->ds_prev_snap_obj != 0 || + spa_version(dp->dp_spa) < SPA_VERSION_ORIGIN || + dp->dp_origin_snap == NULL || ds == dp->dp_origin_snap); mutex_enter(&ds->ds_lock); - if ((DS_MODE_LEVEL(mode) == DS_MODE_PRIMARY && - (ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) && - !DS_MODE_IS_INCONSISTENT(mode)) || - (ds->ds_open_refcount + weight > DS_REF_MAX)) { + if (!dsl_pool_sync_context(dp) && DSL_DATASET_IS_DESTROYED(ds)) { mutex_exit(&ds->ds_lock); - dsl_dataset_close(ds, DS_MODE_NONE, tag); - return (EBUSY); + dmu_buf_rele(ds->ds_dbuf, tag); + return (ENOENT); } - ds->ds_open_refcount += weight; mutex_exit(&ds->ds_lock); - *dsp = ds; return (0); } +static int +dsl_dataset_hold_ref(dsl_dataset_t *ds, void *tag) +{ + dsl_pool_t *dp = ds->ds_dir->dd_pool; + + /* + * In syncing context we don't want the rwlock lock: there + * may be an existing writer waiting for sync phase to + * finish. We don't need to worry about such writers, since + * sync phase is single-threaded, so the writer can't be + * doing anything while we are active. + */ + if (dsl_pool_sync_context(dp)) { + ASSERT(!DSL_DATASET_IS_DESTROYED(ds)); + return (0); + } + + /* + * Normal users will hold the ds_rwlock as a READER until they + * are finished (i.e., call dsl_dataset_rele()). "Owners" will + * drop their READER lock after they set the ds_owner field. + * + * If the dataset is being destroyed, the destroy thread will + * obtain a WRITER lock for exclusive access after it's done its + * open-context work and then change the ds_owner to + * dsl_reaper once destruction is assured. So threads + * may block here temporarily, until the "destructability" of + * the dataset is determined. + */ + ASSERT(!RW_WRITE_HELD(&dp->dp_config_rwlock)); + mutex_enter(&ds->ds_lock); + while (!rw_tryenter(&ds->ds_rwlock, RW_READER)) { + rw_exit(&dp->dp_config_rwlock); + cv_wait(&ds->ds_exclusive_cv, &ds->ds_lock); + if (DSL_DATASET_IS_DESTROYED(ds)) { + mutex_exit(&ds->ds_lock); + dsl_dataset_drop_ref(ds, tag); + rw_enter(&dp->dp_config_rwlock, RW_READER); + return (ENOENT); + } + rw_enter(&dp->dp_config_rwlock, RW_READER); + } + mutex_exit(&ds->ds_lock); + return (0); +} + int -dsl_dataset_open_spa(spa_t *spa, const char *name, int mode, - void *tag, dsl_dataset_t **dsp) +dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag, + dsl_dataset_t **dsp) +{ + int err = dsl_dataset_get_ref(dp, dsobj, tag, dsp); + + if (err) + return (err); + return (dsl_dataset_hold_ref(*dsp, tag)); +} + +int +dsl_dataset_own_obj(dsl_pool_t *dp, uint64_t dsobj, int flags, void *owner, + dsl_dataset_t **dsp) +{ + int err = dsl_dataset_hold_obj(dp, dsobj, owner, dsp); + + ASSERT(DS_MODE_TYPE(flags) != DS_MODE_USER); + + if (err) + return (err); + if (!dsl_dataset_tryown(*dsp, DS_MODE_IS_INCONSISTENT(flags), owner)) { + dsl_dataset_rele(*dsp, owner); + return (EBUSY); + } + return (0); +} + +int +dsl_dataset_hold(const char *name, void *tag, dsl_dataset_t **dsp) { dsl_dir_t *dd; dsl_pool_t *dp; - const char *tail; + const char *snapname; uint64_t obj; - dsl_dataset_t *ds = NULL; int err = 0; - err = dsl_dir_open_spa(spa, name, FTAG, &dd, &tail); + err = dsl_dir_open_spa(NULL, name, FTAG, &dd, &snapname); if (err) return (err); dp = dd->dd_pool; obj = dd->dd_phys->dd_head_dataset_obj; rw_enter(&dp->dp_config_rwlock, RW_READER); - if (obj == 0) { - /* A dataset with no associated objset */ + if (obj) + err = dsl_dataset_get_ref(dp, obj, tag, dsp); + else err = ENOENT; + if (err) goto out; - } - if (tail != NULL) { - objset_t *mos = dp->dp_meta_objset; - uint64_t flags; + err = dsl_dataset_hold_ref(*dsp, tag); - err = dsl_dataset_open_obj(dp, obj, NULL, - DS_MODE_NONE, tag, &ds); - if (err) - goto out; - flags = ds->ds_phys->ds_flags; - obj = ds->ds_phys->ds_snapnames_zapobj; - dsl_dataset_close(ds, DS_MODE_NONE, tag); - ds = NULL; + /* we may be looking for a snapshot */ + if (err == 0 && snapname != NULL) { + dsl_dataset_t *ds = NULL; - if (tail[0] != '@') { + if (*snapname++ != '@') { + dsl_dataset_rele(*dsp, tag); err = ENOENT; goto out; } - tail++; - /* Look for a snapshot */ - if (!DS_MODE_IS_READONLY(mode)) { - err = EROFS; - goto out; + dprintf("looking for snapshot '%s'\n", snapname); + err = dsl_dataset_snap_lookup(*dsp, snapname, &obj); + if (err == 0) + err = dsl_dataset_get_ref(dp, obj, tag, &ds); + dsl_dataset_rele(*dsp, tag); + + ASSERT3U((err == 0), ==, (ds != NULL)); + + if (ds) { + mutex_enter(&ds->ds_lock); + if (ds->ds_snapname[0] == 0) + (void) strlcpy(ds->ds_snapname, snapname, + sizeof (ds->ds_snapname)); + mutex_exit(&ds->ds_lock); + err = dsl_dataset_hold_ref(ds, tag); + *dsp = err ? NULL : ds; } - dprintf("looking for snapshot '%s'\n", tail); - err = dsl_dataset_snap_lookup(mos, flags, obj, tail, &obj); - if (err) - goto out; } - err = dsl_dataset_open_obj(dp, obj, tail, mode, tag, &ds); - out: rw_exit(&dp->dp_config_rwlock); dsl_dir_close(dd, FTAG); - - ASSERT3U((err == 0), ==, (ds != NULL)); - /* ASSERT(ds == NULL || strcmp(name, ds->ds_name) == 0); */ - - *dsp = ds; return (err); } int -dsl_dataset_open(const char *name, int mode, void *tag, dsl_dataset_t **dsp) +dsl_dataset_own(const char *name, int flags, void *owner, dsl_dataset_t **dsp) { - return (dsl_dataset_open_spa(NULL, name, mode, tag, dsp)); + int err = dsl_dataset_hold(name, owner, dsp); + if (err) + return (err); + if ((*dsp)->ds_phys->ds_num_children > 0 && + !DS_MODE_IS_READONLY(flags)) { + dsl_dataset_rele(*dsp, owner); + return (EROFS); + } + if (!dsl_dataset_tryown(*dsp, DS_MODE_IS_INCONSISTENT(flags), owner)) { + dsl_dataset_rele(*dsp, owner); + return (EBUSY); + } + return (0); } void @@ -564,11 +640,11 @@ dsl_dataset_name(dsl_dataset_t *ds, char *name) VERIFY(0 == dsl_dataset_get_snapname(ds)); if (ds->ds_snapname[0]) { (void) strcat(name, "@"); + /* + * We use a "recursive" mutex so that we + * can call dprintf_ds() with ds_lock held. + */ if (!MUTEX_HELD(&ds->ds_lock)) { - /* - * We use a "recursive" mutex so that we - * can call dprintf_ds() with ds_lock held. - */ mutex_enter(&ds->ds_lock); (void) strcat(name, ds->ds_snapname); mutex_exit(&ds->ds_lock); @@ -592,7 +668,6 @@ dsl_dataset_namelen(dsl_dataset_t *ds) if (ds->ds_snapname[0]) { ++result; /* adding one for the @-sign */ if (!MUTEX_HELD(&ds->ds_lock)) { - /* see dsl_datset_name */ mutex_enter(&ds->ds_lock); result += strlen(ds->ds_snapname); mutex_exit(&ds->ds_lock); @@ -606,96 +681,66 @@ dsl_dataset_namelen(dsl_dataset_t *ds) } void -dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag) +dsl_dataset_drop_ref(dsl_dataset_t *ds, void *tag) { - uint64_t weight = ds_refcnt_weight[DS_MODE_LEVEL(mode)]; - mutex_enter(&ds->ds_lock); - ASSERT3U(ds->ds_open_refcount, >=, weight); - ds->ds_open_refcount -= weight; - mutex_exit(&ds->ds_lock); - dmu_buf_rele(ds->ds_dbuf, tag); } void -dsl_dataset_downgrade(dsl_dataset_t *ds, int oldmode, int newmode) +dsl_dataset_rele(dsl_dataset_t *ds, void *tag) { - uint64_t oldweight = ds_refcnt_weight[DS_MODE_LEVEL(oldmode)]; - uint64_t newweight = ds_refcnt_weight[DS_MODE_LEVEL(newmode)]; - mutex_enter(&ds->ds_lock); - ASSERT3U(ds->ds_open_refcount, >=, oldweight); - ASSERT3U(oldweight, >=, newweight); - ds->ds_open_refcount -= oldweight; - ds->ds_open_refcount += newweight; - mutex_exit(&ds->ds_lock); -} - -boolean_t -dsl_dataset_tryupgrade(dsl_dataset_t *ds, int oldmode, int newmode) -{ - boolean_t rv; - uint64_t oldweight = ds_refcnt_weight[DS_MODE_LEVEL(oldmode)]; - uint64_t newweight = ds_refcnt_weight[DS_MODE_LEVEL(newmode)]; - mutex_enter(&ds->ds_lock); - ASSERT3U(ds->ds_open_refcount, >=, oldweight); - ASSERT3U(newweight, >=, oldweight); - if (ds->ds_open_refcount - oldweight + newweight > DS_REF_MAX) { - rv = B_FALSE; - } else { - ds->ds_open_refcount -= oldweight; - ds->ds_open_refcount += newweight; - rv = B_TRUE; + if (!dsl_pool_sync_context(ds->ds_dir->dd_pool)) { + rw_exit(&ds->ds_rwlock); } - mutex_exit(&ds->ds_lock); - return (rv); + dsl_dataset_drop_ref(ds, tag); } void -dsl_dataset_create_root(dsl_pool_t *dp, uint64_t *ddobjp, dmu_tx_t *tx) +dsl_dataset_disown(dsl_dataset_t *ds, void *owner) { - objset_t *mos = dp->dp_meta_objset; - dmu_buf_t *dbuf; - dsl_dataset_phys_t *dsphys; - dsl_dataset_t *ds; - uint64_t dsobj; - dsl_dir_t *dd; + ASSERT((ds->ds_owner == owner && ds->ds_dbuf) || + (DSL_DATASET_IS_DESTROYED(ds) && ds->ds_dbuf == NULL)); - dsl_dir_create_root(mos, ddobjp, tx); - VERIFY(0 == dsl_dir_open_obj(dp, *ddobjp, NULL, FTAG, &dd)); + mutex_enter(&ds->ds_lock); + ds->ds_owner = NULL; + if (RW_WRITE_HELD(&ds->ds_rwlock)) { + rw_exit(&ds->ds_rwlock); + cv_broadcast(&ds->ds_exclusive_cv); + } + mutex_exit(&ds->ds_lock); + if (ds->ds_dbuf) + dsl_dataset_drop_ref(ds, owner); + else + dsl_dataset_evict(ds->ds_dbuf, ds); +} - dsobj = dmu_object_alloc(mos, DMU_OT_DSL_DATASET, 0, - DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx); - VERIFY(0 == dmu_bonus_hold(mos, dsobj, FTAG, &dbuf)); - dmu_buf_will_dirty(dbuf, tx); - dsphys = dbuf->db_data; - dsphys->ds_dir_obj = dd->dd_object; - dsphys->ds_fsid_guid = unique_create(); - (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid, - sizeof (dsphys->ds_guid)); - dsphys->ds_snapnames_zapobj = - zap_create_norm(mos, U8_TEXTPREP_TOUPPER, DMU_OT_DSL_DS_SNAP_MAP, - DMU_OT_NONE, 0, tx); - dsphys->ds_creation_time = gethrestime_sec(); - dsphys->ds_creation_txg = tx->tx_txg; - dsphys->ds_deadlist_obj = - bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); - if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE) - dsphys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE; - dmu_buf_rele(dbuf, FTAG); +boolean_t +dsl_dataset_tryown(dsl_dataset_t *ds, boolean_t inconsistentok, void *owner) +{ + boolean_t gotit = FALSE; - dmu_buf_will_dirty(dd->dd_dbuf, tx); - dd->dd_phys->dd_head_dataset_obj = dsobj; - dsl_dir_close(dd, FTAG); + mutex_enter(&ds->ds_lock); + if (ds->ds_owner == NULL && + (!DS_IS_INCONSISTENT(ds) || inconsistentok)) { + ds->ds_owner = owner; + if (!dsl_pool_sync_context(ds->ds_dir->dd_pool)) + rw_exit(&ds->ds_rwlock); + gotit = TRUE; + } + mutex_exit(&ds->ds_lock); + return (gotit); +} - VERIFY(0 == - dsl_dataset_open_obj(dp, dsobj, NULL, DS_MODE_NONE, FTAG, &ds)); - (void) dmu_objset_create_impl(dp->dp_spa, ds, - &ds->ds_phys->ds_bp, DMU_OST_ZFS, tx); - dsl_dataset_close(ds, DS_MODE_NONE, FTAG); +void +dsl_dataset_make_exclusive(dsl_dataset_t *ds, void *owner) +{ + ASSERT3P(owner, ==, ds->ds_owner); + if (!RW_WRITE_HELD(&ds->ds_rwlock)) + rw_enter(&ds->ds_rwlock, RW_WRITER); } uint64_t -dsl_dataset_create_sync_impl(dsl_dir_t *dd, dsl_dataset_t *origin, +dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, uint64_t flags, dmu_tx_t *tx) { dsl_pool_t *dp = dd->dd_pool; @@ -704,6 +749,9 @@ dsl_dataset_create_sync_impl(dsl_dir_t *dd, dsl_dataset_t *origin, uint64_t dsobj; objset_t *mos = dp->dp_meta_objset; + if (origin == NULL) + origin = dp->dp_origin_snap; + ASSERT(origin == NULL || origin->ds_dir->dd_pool == dp); ASSERT(origin == NULL || origin->ds_phys->ds_num_children > 0); ASSERT(dmu_tx_is_syncing(tx)); @@ -714,6 +762,7 @@ dsl_dataset_create_sync_impl(dsl_dir_t *dd, dsl_dataset_t *origin, VERIFY(0 == dmu_bonus_hold(mos, dsobj, FTAG, &dbuf)); dmu_buf_will_dirty(dbuf, tx); dsphys = dbuf->db_data; + bzero(dsphys, sizeof (dsl_dataset_phys_t)); dsphys->ds_dir_obj = dd->dd_object; dsphys->ds_flags = flags; dsphys->ds_fsid_guid = unique_create(); @@ -723,7 +772,7 @@ dsl_dataset_create_sync_impl(dsl_dir_t *dd, dsl_dataset_t *origin, zap_create_norm(mos, U8_TEXTPREP_TOUPPER, DMU_OT_DSL_DS_SNAP_MAP, DMU_OT_NONE, 0, tx); dsphys->ds_creation_time = gethrestime_sec(); - dsphys->ds_creation_txg = tx->tx_txg; + dsphys->ds_creation_txg = tx->tx_txg == TXG_INITIAL ? 1 : tx->tx_txg; dsphys->ds_deadlist_obj = bplist_create(mos, DSL_DEADLIST_BLOCKSIZE, tx); @@ -743,6 +792,17 @@ dsl_dataset_create_sync_impl(dsl_dir_t *dd, dsl_dataset_t *origin, dmu_buf_will_dirty(origin->ds_dbuf, tx); origin->ds_phys->ds_num_children++; + if (spa_version(dp->dp_spa) >= SPA_VERSION_NEXT_CLONES) { + if (origin->ds_phys->ds_next_clones_obj == 0) { + origin->ds_phys->ds_next_clones_obj = + zap_create(mos, + DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx); + } + VERIFY(0 == zap_add_int(mos, + origin->ds_phys->ds_next_clones_obj, + dsobj, tx)); + } + dmu_buf_will_dirty(dd->dd_dbuf, tx); dd->dd_phys->dd_origin_obj = origin->ds_object; } @@ -768,10 +828,10 @@ dsl_dataset_create_sync(dsl_dir_t *pdd, const char *lastname, ASSERT(lastname[0] != '@'); - ddobj = dsl_dir_create_sync(pdd, lastname, tx); + ddobj = dsl_dir_create_sync(dp, pdd, lastname, tx); VERIFY(0 == dsl_dir_open_obj(dp, ddobj, lastname, FTAG, &dd)); - dsobj = dsl_dataset_create_sync_impl(dd, origin, flags, tx); + dsobj = dsl_dataset_create_sync_dd(dd, origin, flags, tx); dsl_deleg_set_create_perms(dd, tx, cr); @@ -796,21 +856,24 @@ dsl_snapshot_destroy_one(char *name, void *arg) (void) strcat(name, "@"); (void) strcat(name, da->snapname); - err = dsl_dataset_open(name, - DS_MODE_EXCLUSIVE | DS_MODE_READONLY | DS_MODE_INCONSISTENT, + err = dsl_dataset_own(name, DS_MODE_READONLY | DS_MODE_INCONSISTENT, da->dstg, &ds); cp = strchr(name, '@'); *cp = '\0'; - if (err == ENOENT) - return (0); - if (err) { + if (err == 0) { + dsl_dataset_make_exclusive(ds, da->dstg); + if (ds->ds_user_ptr) { + ds->ds_user_evict_func(ds, ds->ds_user_ptr); + ds->ds_user_ptr = NULL; + } + dsl_sync_task_create(da->dstg, dsl_dataset_destroy_check, + dsl_dataset_destroy_sync, ds, da->dstg, 0); + } else if (err == ENOENT) { + err = 0; + } else { (void) strcpy(da->failed, name); - return (err); } - - dsl_sync_task_create(da->dstg, dsl_dataset_destroy_check, - dsl_dataset_destroy_sync, ds, da->dstg, 0); - return (0); + return (err); } /* @@ -841,16 +904,14 @@ dsl_snapshots_destroy(char *fsname, char *snapname) for (dst = list_head(&da.dstg->dstg_tasks); dst; dst = list_next(&da.dstg->dstg_tasks, dst)) { dsl_dataset_t *ds = dst->dst_arg1; + /* + * Return the file system name that triggered the error + */ if (dst->dst_err) { dsl_dataset_name(ds, fsname); *strchr(fsname, '@') = '\0'; } - /* - * If it was successful, destroy_sync would have - * closed the ds - */ - if (err) - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, da.dstg); + dsl_dataset_disown(ds, da.dstg); } dsl_sync_task_group_destroy(da.dstg); @@ -859,9 +920,8 @@ dsl_snapshots_destroy(char *fsname, char *snapname) } /* - * ds must be opened EXCLUSIVE or PRIMARY. on return (whether - * successful or not), ds will be closed and caller can no longer - * dereference it. + * ds must be opened as OWNER. On return (whether successful or not), + * ds will be closed and caller can no longer dereference it. */ int dsl_dataset_destroy(dsl_dataset_t *ds, void *tag) @@ -872,16 +932,14 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag) dsl_dir_t *dd; uint64_t obj; - if (ds->ds_open_refcount != DS_REF_MAX) { - if (dsl_dataset_tryupgrade(ds, DS_MODE_PRIMARY, - DS_MODE_EXCLUSIVE) == 0) { - dsl_dataset_close(ds, DS_MODE_PRIMARY, tag); - return (EBUSY); - } - } - if (dsl_dataset_is_snapshot(ds)) { /* Destroying a snapshot is simpler */ + dsl_dataset_make_exclusive(ds, tag); + + if (ds->ds_user_ptr) { + ds->ds_user_evict_func(ds, ds->ds_user_ptr); + ds->ds_user_ptr = NULL; + } err = dsl_sync_task_do(ds->ds_dir->dd_pool, dsl_dataset_destroy_check, dsl_dataset_destroy_sync, ds, tag, 0); @@ -909,34 +967,17 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag) */ for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE, ds->ds_phys->ds_prev_snap_txg)) { - dmu_tx_t *tx = dmu_tx_create(os); - dmu_tx_hold_free(tx, obj, 0, DMU_OBJECT_END); - dmu_tx_hold_bonus(tx, obj); - err = dmu_tx_assign(tx, TXG_WAIT); - if (err) { - /* - * Perhaps there is not enough disk - * space. Just deal with it from - * dsl_dataset_destroy_sync(). - */ - dmu_tx_abort(tx); - continue; - } - VERIFY(0 == dmu_object_free(os, obj, tx)); - dmu_tx_commit(tx); + /* + * Ignore errors, if there is not enough disk space + * we will deal with it in dsl_dataset_destroy_sync(). + */ + (void) dmu_free_object(os, obj); } - /* Make sure it's not dirty before we finish destroying it. */ - txg_wait_synced(dd->dd_pool, 0); dmu_objset_close(os); if (err != ESRCH) goto out; - if (ds->ds_user_ptr) { - ds->ds_user_evict_func(ds, ds->ds_user_ptr); - ds->ds_user_ptr = NULL; - } - rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); err = dsl_dir_open_obj(dd->dd_pool, dd->dd_object, NULL, FTAG, &dd); rw_exit(&dd->dd_pool->dp_config_rwlock); @@ -944,9 +985,23 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag) if (err) goto out; + if (ds->ds_user_ptr) { + /* + * We need to sync out all in-flight IO before we try + * to evict (the dataset evict func is trying to clear + * the cached entries for this dataset in the ARC). + */ + txg_wait_synced(dd->dd_pool, 0); + } + /* * Blow away the dsl_dir + head dataset. */ + dsl_dataset_make_exclusive(ds, tag); + if (ds->ds_user_ptr) { + ds->ds_user_evict_func(ds, ds->ds_user_ptr); + ds->ds_user_ptr = NULL; + } dstg = dsl_sync_task_group_create(ds->ds_dir->dd_pool); dsl_sync_task_create(dstg, dsl_dataset_destroy_check, dsl_dataset_destroy_sync, ds, tag, 0); @@ -954,23 +1009,31 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag) dsl_dir_destroy_sync, dd, FTAG, 0); err = dsl_sync_task_group_wait(dstg); dsl_sync_task_group_destroy(dstg); - /* if it is successful, *destroy_sync will close the ds+dd */ + /* if it is successful, dsl_dir_destroy_sync will close the dd */ if (err) dsl_dir_close(dd, FTAG); out: - if (err) - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, tag); + dsl_dataset_disown(ds, tag); return (err); } int dsl_dataset_rollback(dsl_dataset_t *ds, dmu_objset_type_t ost) { - ASSERT3U(ds->ds_open_refcount, ==, DS_REF_MAX); + int err; - return (dsl_sync_task_do(ds->ds_dir->dd_pool, + ASSERT(ds->ds_owner); + + dsl_dataset_make_exclusive(ds, ds->ds_owner); + err = dsl_sync_task_do(ds->ds_dir->dd_pool, dsl_dataset_rollback_check, dsl_dataset_rollback_sync, - ds, &ost, 0)); + ds, &ost, 0); + /* drop exclusive access */ + mutex_enter(&ds->ds_lock); + rw_exit(&ds->ds_rwlock); + cv_broadcast(&ds->ds_exclusive_cv); + mutex_exit(&ds->ds_lock); + return (err); } void * @@ -1086,31 +1149,24 @@ dsl_dataset_unique(dsl_dataset_t *ds) } struct killarg { - int64_t *usedp; - int64_t *compressedp; - int64_t *uncompressedp; + dsl_dataset_t *ds; zio_t *zio; dmu_tx_t *tx; }; +/* ARGSUSED */ static int -kill_blkptr(traverse_blk_cache_t *bc, spa_t *spa, void *arg) +kill_blkptr(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb, + const dnode_phys_t *dnp, void *arg) { struct killarg *ka = arg; - blkptr_t *bp = &bc->bc_blkptr; - ASSERT3U(bc->bc_errno, ==, 0); + if (bp == NULL) + return (0); + + ASSERT3U(bp->blk_birth, >, ka->ds->ds_phys->ds_prev_snap_txg); + (void) dsl_dataset_block_kill(ka->ds, bp, ka->zio, ka->tx); - /* - * Since this callback is not called concurrently, no lock is - * needed on the accounting values. - */ - *ka->usedp += bp_get_dasize(spa, bp); - *ka->compressedp += BP_GET_PSIZE(bp); - *ka->uncompressedp += BP_GET_UCSIZE(bp); - /* XXX check for EIO? */ - (void) arc_free(ka->zio, spa, ka->tx->tx_txg, bp, NULL, NULL, - ARC_NOWAIT); return (0); } @@ -1134,7 +1190,7 @@ dsl_dataset_rollback_check(void *arg1, void *arg2, dmu_tx_t *tx) return (EINVAL); /* - * If we made changes this txg, traverse_dsl_dataset won't find + * If we made changes this txg, traverse_dataset won't find * them. Try again. */ if (ds->ds_phys->ds_bp.blk_birth >= tx->tx_txg) @@ -1164,7 +1220,7 @@ dsl_dataset_rollback_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) * We need to make sure that the objset_impl_t is reopened after * we do the rollback, otherwise it will have the wrong * objset_phys_t. Normally this would happen when this - * DS_MODE_EXCLUSIVE dataset-open is closed, thus causing the + * dataset-open is closed, thus causing the * dataset to be immediately evicted. But when doing "zfs recv * -F", we reopen the objset before that, so that there is no * window where the dataset is closed and inconsistent. @@ -1173,6 +1229,16 @@ dsl_dataset_rollback_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) ds->ds_user_ptr = NULL; } + /* Transfer space that was freed since last snap back to the head. */ + { + uint64_t used; + + VERIFY(0 == bplist_space_birthrange(&ds->ds_deadlist, + ds->ds_origin_txg, UINT64_MAX, &used)); + dsl_dir_transfer_space(ds->ds_dir, used, + DD_USED_SNAP, DD_USED_HEAD, tx); + } + /* Zero out the deadlist. */ bplist_close(&ds->ds_deadlist); bplist_destroy(mos, ds->ds_phys->ds_deadlist_obj, tx); @@ -1184,31 +1250,29 @@ dsl_dataset_rollback_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) { /* Free blkptrs that we gave birth to */ zio_t *zio; - int64_t used = 0, compressed = 0, uncompressed = 0; struct killarg ka; - int64_t delta; zio = zio_root(tx->tx_pool->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); - ka.usedp = &used; - ka.compressedp = &compressed; - ka.uncompressedp = &uncompressed; + ka.ds = ds; ka.zio = zio; ka.tx = tx; - (void) traverse_dsl_dataset(ds, ds->ds_phys->ds_prev_snap_txg, - ADVANCE_POST, kill_blkptr, &ka); + (void) traverse_dataset(ds, ds->ds_phys->ds_prev_snap_txg, + TRAVERSE_POST, kill_blkptr, &ka); (void) zio_wait(zio); - - /* only deduct space beyond any refreservation */ - delta = parent_delta(ds, -used); - dsl_dir_diduse_space(ds->ds_dir, - delta, -compressed, -uncompressed, tx); } - if (ds->ds_prev) { + ASSERT(!(ds->ds_phys->ds_flags & DS_FLAG_UNIQUE_ACCURATE) || + ds->ds_phys->ds_unique_bytes == 0); + + if (ds->ds_prev && ds->ds_prev != ds->ds_dir->dd_pool->dp_origin_snap) { /* Change our contents to that of the prev snapshot */ + ASSERT3U(ds->ds_prev->ds_object, ==, ds->ds_phys->ds_prev_snap_obj); + ASSERT3U(ds->ds_phys->ds_used_bytes, <=, + ds->ds_prev->ds_phys->ds_used_bytes); + ds->ds_phys->ds_bp = ds->ds_prev->ds_phys->ds_bp; ds->ds_phys->ds_used_bytes = ds->ds_prev->ds_phys->ds_used_bytes; @@ -1217,22 +1281,30 @@ dsl_dataset_rollback_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) ds->ds_phys->ds_uncompressed_bytes = ds->ds_prev->ds_phys->ds_uncompressed_bytes; ds->ds_phys->ds_flags = ds->ds_prev->ds_phys->ds_flags; - ds->ds_phys->ds_unique_bytes = 0; if (ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) { dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx); ds->ds_prev->ds_phys->ds_unique_bytes = 0; } } else { - /* Zero out our contents, recreate objset */ + objset_impl_t *osi; + + ASSERT3U(ds->ds_phys->ds_used_bytes, ==, 0); + ASSERT3U(ds->ds_phys->ds_compressed_bytes, ==, 0); + ASSERT3U(ds->ds_phys->ds_uncompressed_bytes, ==, 0); + bzero(&ds->ds_phys->ds_bp, sizeof (blkptr_t)); - ds->ds_phys->ds_used_bytes = 0; - ds->ds_phys->ds_compressed_bytes = 0; - ds->ds_phys->ds_uncompressed_bytes = 0; ds->ds_phys->ds_flags = 0; ds->ds_phys->ds_unique_bytes = 0; - (void) dmu_objset_create_impl(ds->ds_dir->dd_pool->dp_spa, ds, + if (spa_version(ds->ds_dir->dd_pool->dp_spa) >= + SPA_VERSION_UNIQUE_ACCURATE) + ds->ds_phys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE; + + osi = dmu_objset_create_impl(ds->ds_dir->dd_pool->dp_spa, ds, &ds->ds_phys->ds_bp, *ost, tx); +#ifdef _KERNEL + zfs_create_fs(&osi->os, kcred, NULL, tx); +#endif } spa_history_internal_log(LOG_DS_ROLLBACK, ds->ds_dir->dd_pool->dp_spa, @@ -1292,6 +1364,9 @@ dsl_dataset_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx) { dsl_dataset_t *ds = arg1; + /* we have an owner hold, so noone else can destroy us */ + ASSERT(!DSL_DATASET_IS_DESTROYED(ds)); + /* Can't delete a branch point. */ if (ds->ds_phys->ds_num_children > 1) return (EEXIST); @@ -1316,11 +1391,50 @@ dsl_dataset_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx) return (0); } +struct refsarg { + kmutex_t lock; + boolean_t gone; + kcondvar_t cv; +}; + +/* ARGSUSED */ +static void +dsl_dataset_refs_gone(dmu_buf_t *db, void *argv) +{ + struct refsarg *arg = argv; + + mutex_enter(&arg->lock); + arg->gone = TRUE; + cv_signal(&arg->cv); + mutex_exit(&arg->lock); +} + +static void +dsl_dataset_drain_refs(dsl_dataset_t *ds, void *tag) +{ + struct refsarg arg; + + mutex_init(&arg.lock, NULL, MUTEX_DEFAULT, NULL); + cv_init(&arg.cv, NULL, CV_DEFAULT, NULL); + arg.gone = FALSE; + (void) dmu_buf_update_user(ds->ds_dbuf, ds, &arg, &ds->ds_phys, + dsl_dataset_refs_gone); + dmu_buf_rele(ds->ds_dbuf, tag); + mutex_enter(&arg.lock); + while (!arg.gone) + cv_wait(&arg.cv, &arg.lock); + ASSERT(arg.gone); + mutex_exit(&arg.lock); + ds->ds_dbuf = NULL; + ds->ds_phys = NULL; + mutex_destroy(&arg.lock); + cv_destroy(&arg.cv); +} + void dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) { dsl_dataset_t *ds = arg1; - int64_t used = 0, compressed = 0, uncompressed = 0; zio_t *zio; int err; int after_branch_point = FALSE; @@ -1329,12 +1443,18 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) dsl_dataset_t *ds_prev = NULL; uint64_t obj; - ASSERT3U(ds->ds_open_refcount, ==, DS_REF_MAX); + ASSERT(ds->ds_owner); ASSERT3U(ds->ds_phys->ds_num_children, <=, 1); ASSERT(ds->ds_prev == NULL || ds->ds_prev->ds_phys->ds_next_snap_obj != ds->ds_object); ASSERT3U(ds->ds_phys->ds_bp.blk_birth, <=, tx->tx_txg); + /* signal any waiters that this dataset is going away */ + mutex_enter(&ds->ds_lock); + ds->ds_owner = dsl_reaper; + cv_broadcast(&ds->ds_exclusive_cv); + mutex_exit(&ds->ds_lock); + /* Remove our reservation */ if (ds->ds_reserved != 0) { uint64_t val = 0; @@ -1344,20 +1464,31 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock)); + dsl_pool_ds_destroyed(ds, tx); + obj = ds->ds_object; if (ds->ds_phys->ds_prev_snap_obj != 0) { if (ds->ds_prev) { ds_prev = ds->ds_prev; } else { - VERIFY(0 == dsl_dataset_open_obj(dp, - ds->ds_phys->ds_prev_snap_obj, NULL, - DS_MODE_NONE, FTAG, &ds_prev)); + VERIFY(0 == dsl_dataset_hold_obj(dp, + ds->ds_phys->ds_prev_snap_obj, FTAG, &ds_prev)); } after_branch_point = (ds_prev->ds_phys->ds_next_snap_obj != obj); dmu_buf_will_dirty(ds_prev->ds_dbuf, tx); + if (after_branch_point && + ds_prev->ds_phys->ds_next_clones_obj != 0) { + VERIFY(0 == zap_remove_int(mos, + ds_prev->ds_phys->ds_next_clones_obj, obj, tx)); + if (ds->ds_phys->ds_next_snap_obj != 0) { + VERIFY(0 == zap_add_int(mos, + ds_prev->ds_phys->ds_next_clones_obj, + ds->ds_phys->ds_next_snap_obj, tx)); + } + } if (after_branch_point && ds->ds_phys->ds_next_snap_obj == 0) { /* This clone is toast. */ @@ -1376,12 +1507,10 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) dsl_dataset_t *ds_next; uint64_t itor = 0; uint64_t old_unique; + int64_t used = 0, compressed = 0, uncompressed = 0; - spa_scrub_restart(dp->dp_spa, tx->tx_txg); - - VERIFY(0 == dsl_dataset_open_obj(dp, - ds->ds_phys->ds_next_snap_obj, NULL, - DS_MODE_NONE, FTAG, &ds_next)); + VERIFY(0 == dsl_dataset_hold_obj(dp, + ds->ds_phys->ds_next_snap_obj, FTAG, &ds_next)); ASSERT3U(ds_next->ds_phys->ds_prev_snap_obj, ==, obj); old_unique = dsl_dataset_unique(ds_next); @@ -1402,8 +1531,7 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) * * XXX we're doing this long task with the config lock held */ - while (bplist_iterate(&ds_next->ds_deadlist, &itor, - &bp) == 0) { + while (bplist_iterate(&ds_next->ds_deadlist, &itor, &bp) == 0) { if (bp.blk_birth <= ds->ds_phys->ds_prev_snap_txg) { VERIFY(0 == bplist_enqueue(&ds->ds_deadlist, &bp, tx)); @@ -1418,16 +1546,23 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) compressed += BP_GET_PSIZE(&bp); uncompressed += BP_GET_UCSIZE(&bp); /* XXX check return value? */ - (void) arc_free(zio, dp->dp_spa, tx->tx_txg, + (void) dsl_free(zio, dp, tx->tx_txg, &bp, NULL, NULL, ARC_NOWAIT); } } + ASSERT3U(used, ==, ds->ds_phys->ds_unique_bytes); + + /* change snapused */ + dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP, + -used, -compressed, -uncompressed, tx); + /* free next's deadlist */ bplist_close(&ds_next->ds_deadlist); bplist_destroy(mos, ds_next->ds_phys->ds_deadlist_obj, tx); /* set next's deadlist to our deadlist */ + bplist_close(&ds->ds_deadlist); ds_next->ds_phys->ds_deadlist_obj = ds->ds_phys->ds_deadlist_obj; VERIFY(0 == bplist_open(&ds_next->ds_deadlist, mos, @@ -1448,34 +1583,28 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) * config lock held */ dsl_dataset_t *ds_after_next; + uint64_t space; - VERIFY(0 == dsl_dataset_open_obj(dp, - ds_next->ds_phys->ds_next_snap_obj, NULL, - DS_MODE_NONE, FTAG, &ds_after_next)); - itor = 0; - while (bplist_iterate(&ds_after_next->ds_deadlist, - &itor, &bp) == 0) { - if (bp.blk_birth > - ds->ds_phys->ds_prev_snap_txg && - bp.blk_birth <= - ds->ds_phys->ds_creation_txg) { - ds_next->ds_phys->ds_unique_bytes += - bp_get_dasize(dp->dp_spa, &bp); - } - } + VERIFY(0 == dsl_dataset_hold_obj(dp, + ds_next->ds_phys->ds_next_snap_obj, + FTAG, &ds_after_next)); - dsl_dataset_close(ds_after_next, DS_MODE_NONE, FTAG); + VERIFY(0 == + bplist_space_birthrange(&ds_after_next->ds_deadlist, + ds->ds_phys->ds_prev_snap_txg, + ds->ds_phys->ds_creation_txg, &space)); + ds_next->ds_phys->ds_unique_bytes += space; + + dsl_dataset_rele(ds_after_next, FTAG); ASSERT3P(ds_next->ds_prev, ==, NULL); } else { ASSERT3P(ds_next->ds_prev, ==, ds); - dsl_dataset_close(ds_next->ds_prev, DS_MODE_NONE, - ds_next); + dsl_dataset_drop_ref(ds_next->ds_prev, ds_next); + ds_next->ds_prev = NULL; if (ds_prev) { - VERIFY(0 == dsl_dataset_open_obj(dp, - ds->ds_phys->ds_prev_snap_obj, NULL, - DS_MODE_NONE, ds_next, &ds_next->ds_prev)); - } else { - ds_next->ds_prev = NULL; + VERIFY(0 == dsl_dataset_get_ref(dp, + ds->ds_phys->ds_prev_snap_obj, + ds_next, &ds_next->ds_prev)); } dsl_dataset_recalc_head_uniq(ds_next); @@ -1493,18 +1622,11 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) ASSERT(old_unique <= new_unique); mrsdelta = MIN(new_unique - old_unique, ds_next->ds_reserved - old_unique); - dsl_dir_diduse_space(ds->ds_dir, -mrsdelta, - 0, 0, tx); + dsl_dir_diduse_space(ds->ds_dir, + DD_USED_REFRSRV, -mrsdelta, 0, 0, tx); } } - dsl_dataset_close(ds_next, DS_MODE_NONE, FTAG); - - /* - * NB: unique_bytes might not be accurate for the head objset. - * Before SPA_VERSION 9, we didn't update its value when we - * deleted the most recent snapshot. - */ - ASSERT3U(used, ==, ds->ds_phys->ds_unique_bytes); + dsl_dataset_rele(ds_next, FTAG); } else { /* * There's no next snapshot, so this is a head dataset. @@ -1523,76 +1645,71 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) * Free everything that we point to (that's born after * the previous snapshot, if we are a clone) * - * XXX we're doing this long task with the config lock held + * NB: this should be very quick, because we already + * freed all the objects in open context. */ - ka.usedp = &used; - ka.compressedp = &compressed; - ka.uncompressedp = &uncompressed; + ka.ds = ds; ka.zio = zio; ka.tx = tx; - err = traverse_dsl_dataset(ds, ds->ds_phys->ds_prev_snap_txg, - ADVANCE_POST, kill_blkptr, &ka); + err = traverse_dataset(ds, ds->ds_phys->ds_prev_snap_txg, + TRAVERSE_POST, kill_blkptr, &ka); ASSERT3U(err, ==, 0); - ASSERT(spa_version(dp->dp_spa) < - SPA_VERSION_UNIQUE_ACCURATE || - used == ds->ds_phys->ds_unique_bytes); + ASSERT(spa_version(dp->dp_spa) < SPA_VERSION_UNIQUE_ACCURATE || + ds->ds_phys->ds_unique_bytes == 0); } err = zio_wait(zio); ASSERT3U(err, ==, 0); - dsl_dir_diduse_space(ds->ds_dir, -used, -compressed, -uncompressed, tx); - - if (ds->ds_phys->ds_snapnames_zapobj) { - err = zap_destroy(mos, ds->ds_phys->ds_snapnames_zapobj, tx); - ASSERT(err == 0); - } - if (ds->ds_dir->dd_phys->dd_head_dataset_obj == ds->ds_object) { - /* Erase the link in the dataset */ + /* Erase the link in the dir */ dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx); ds->ds_dir->dd_phys->dd_head_dataset_obj = 0; - /* - * dsl_dir_sync_destroy() called us, they'll destroy - * the dataset. - */ + ASSERT(ds->ds_phys->ds_snapnames_zapobj != 0); + err = zap_destroy(mos, ds->ds_phys->ds_snapnames_zapobj, tx); + ASSERT(err == 0); } else { /* remove from snapshot namespace */ dsl_dataset_t *ds_head; - VERIFY(0 == dsl_dataset_open_obj(dp, - ds->ds_dir->dd_phys->dd_head_dataset_obj, NULL, - DS_MODE_NONE, FTAG, &ds_head)); + ASSERT(ds->ds_phys->ds_snapnames_zapobj == 0); + VERIFY(0 == dsl_dataset_hold_obj(dp, + ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ds_head)); VERIFY(0 == dsl_dataset_get_snapname(ds)); #ifdef ZFS_DEBUG { uint64_t val; - err = dsl_dataset_snap_lookup(mos, - ds_head->ds_phys->ds_flags, - ds_head->ds_phys->ds_snapnames_zapobj, + err = dsl_dataset_snap_lookup(ds_head, ds->ds_snapname, &val); ASSERT3U(err, ==, 0); ASSERT3U(val, ==, obj); } #endif - err = dsl_dataset_snap_remove(mos, - ds_head->ds_phys->ds_flags, - ds_head->ds_phys->ds_snapnames_zapobj, - ds->ds_snapname, tx); + err = dsl_dataset_snap_remove(ds_head, ds->ds_snapname, tx); ASSERT(err == 0); - dsl_dataset_close(ds_head, DS_MODE_NONE, FTAG); + dsl_dataset_rele(ds_head, FTAG); } if (ds_prev && ds->ds_prev != ds_prev) - dsl_dataset_close(ds_prev, DS_MODE_NONE, FTAG); + dsl_dataset_rele(ds_prev, FTAG); spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx); spa_history_internal_log(LOG_DS_DESTROY, dp->dp_spa, tx, cr, "dataset = %llu", ds->ds_object); - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, tag); + if (ds->ds_phys->ds_next_clones_obj != 0) { + uint64_t count; + ASSERT(0 == zap_count(mos, + ds->ds_phys->ds_next_clones_obj, &count) && count == 0); + VERIFY(0 == dmu_object_free(mos, + ds->ds_phys->ds_next_clones_obj, tx)); + } + if (ds->ds_phys->ds_props_obj != 0) + VERIFY(0 == zap_destroy(mos, ds->ds_phys->ds_props_obj, tx)); + dsl_dir_close(ds->ds_dir, ds); + ds->ds_dir = NULL; + dsl_dataset_drain_refs(ds, tag); VERIFY(0 == dmu_object_free(mos, obj, tx)); - } static int @@ -1628,7 +1745,6 @@ dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx) { dsl_dataset_t *ds = arg1; const char *snapname = arg2; - objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; int err; uint64_t value; @@ -1642,8 +1758,7 @@ dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx) /* * Check for conflicting name snapshot name. */ - err = dsl_dataset_snap_lookup(mos, ds->ds_phys->ds_flags, - ds->ds_phys->ds_snapnames_zapobj, snapname, &value); + err = dsl_dataset_snap_lookup(ds, snapname, &value); if (err == 0) return (EEXIST); if (err != ENOENT) @@ -1672,18 +1787,26 @@ dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) dsl_pool_t *dp = ds->ds_dir->dd_pool; dmu_buf_t *dbuf; dsl_dataset_phys_t *dsphys; - uint64_t dsobj; + uint64_t dsobj, crtxg; objset_t *mos = dp->dp_meta_objset; int err; - spa_scrub_restart(dp->dp_spa, tx->tx_txg); ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock)); + /* + * The origin's ds_creation_txg has to be < TXG_INITIAL + */ + if (strcmp(snapname, ORIGIN_DIR_NAME) == 0) + crtxg = 1; + else + crtxg = tx->tx_txg; + dsobj = dmu_object_alloc(mos, DMU_OT_DSL_DATASET, 0, DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx); VERIFY(0 == dmu_bonus_hold(mos, dsobj, FTAG, &dbuf)); dmu_buf_will_dirty(dbuf, tx); dsphys = dbuf->db_data; + bzero(dsphys, sizeof (dsl_dataset_phys_t)); dsphys->ds_dir_obj = ds->ds_dir->dd_object; dsphys->ds_fsid_guid = unique_create(); (void) random_get_pseudo_bytes((void*)&dsphys->ds_guid, @@ -1693,7 +1816,7 @@ dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) dsphys->ds_next_snap_obj = ds->ds_object; dsphys->ds_num_children = 1; dsphys->ds_creation_time = gethrestime_sec(); - dsphys->ds_creation_txg = tx->tx_txg; + dsphys->ds_creation_txg = crtxg; dsphys->ds_deadlist_obj = ds->ds_phys->ds_deadlist_obj; dsphys->ds_used_bytes = ds->ds_phys->ds_used_bytes; dsphys->ds_compressed_bytes = ds->ds_phys->ds_compressed_bytes; @@ -1704,6 +1827,8 @@ dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) ASSERT3U(ds->ds_prev != 0, ==, ds->ds_phys->ds_prev_snap_obj != 0); if (ds->ds_prev) { + uint64_t next_clones_obj = + ds->ds_prev->ds_phys->ds_next_clones_obj; ASSERT(ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object || ds->ds_prev->ds_phys->ds_num_children > 1); @@ -1712,6 +1837,11 @@ dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) ASSERT3U(ds->ds_phys->ds_prev_snap_txg, ==, ds->ds_prev->ds_phys->ds_creation_txg); ds->ds_prev->ds_phys->ds_next_snap_obj = dsobj; + } else if (next_clones_obj != 0) { + VERIFY3U(0, ==, zap_remove_int(mos, + next_clones_obj, dsphys->ds_next_snap_obj, tx)); + VERIFY3U(0, ==, zap_add_int(mos, + next_clones_obj, dsobj, tx)); } } @@ -1722,14 +1852,15 @@ dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) */ if (ds->ds_reserved) { int64_t add = MIN(dsl_dataset_unique(ds), ds->ds_reserved); - dsl_dir_diduse_space(ds->ds_dir, add, 0, 0, tx); + dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, + add, 0, 0, tx); } bplist_close(&ds->ds_deadlist); dmu_buf_will_dirty(ds->ds_dbuf, tx); ASSERT3U(ds->ds_phys->ds_prev_snap_txg, <, tx->tx_txg); ds->ds_phys->ds_prev_snap_obj = dsobj; - ds->ds_phys->ds_prev_snap_txg = tx->tx_txg; + ds->ds_phys->ds_prev_snap_txg = crtxg; ds->ds_phys->ds_unique_bytes = 0; if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE) ds->ds_phys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE; @@ -1744,10 +1875,11 @@ dsl_dataset_snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) ASSERT(err == 0); if (ds->ds_prev) - dsl_dataset_close(ds->ds_prev, DS_MODE_NONE, ds); - VERIFY(0 == dsl_dataset_open_obj(dp, - ds->ds_phys->ds_prev_snap_obj, snapname, - DS_MODE_NONE, ds, &ds->ds_prev)); + dsl_dataset_drop_ref(ds->ds_prev, ds); + VERIFY(0 == dsl_dataset_get_ref(dp, + ds->ds_phys->ds_prev_snap_obj, ds, &ds->ds_prev)); + + dsl_pool_ds_snapshotted(ds, tx); spa_history_internal_log(LOG_DS_SNAPSHOT, dp->dp_spa, tx, cr, "dataset = %llu", dsobj); @@ -1790,6 +1922,8 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv) ds->ds_quota); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRESERVATION, ds->ds_reserved); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_GUID, + ds->ds_phys->ds_guid); if (ds->ds_phys->ds_next_snap_obj) { /* @@ -1818,14 +1952,13 @@ dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat) /* clone origin is really a dsl_dir thing... */ rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER); - if (ds->ds_dir->dd_phys->dd_origin_obj) { + if (dsl_dir_is_clone(ds->ds_dir)) { dsl_dataset_t *ods; - VERIFY(0 == dsl_dataset_open_obj(ds->ds_dir->dd_pool, - ds->ds_dir->dd_phys->dd_origin_obj, - NULL, DS_MODE_NONE, FTAG, &ods)); + VERIFY(0 == dsl_dataset_get_ref(ds->ds_dir->dd_pool, + ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &ods)); dsl_dataset_name(ods, stat->dds_origin); - dsl_dataset_close(ods, DS_MODE_NONE, FTAG); + dsl_dataset_drop_ref(ods, FTAG); } rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock); } @@ -1881,20 +2014,18 @@ dsl_dataset_snapshot_rename_check(void *arg1, void *arg2, dmu_tx_t *tx) dsl_dataset_t *ds = arg1; char *newsnapname = arg2; dsl_dir_t *dd = ds->ds_dir; - objset_t *mos = dd->dd_pool->dp_meta_objset; dsl_dataset_t *hds; uint64_t val; int err; - err = dsl_dataset_open_obj(dd->dd_pool, - dd->dd_phys->dd_head_dataset_obj, NULL, DS_MODE_NONE, FTAG, &hds); + err = dsl_dataset_hold_obj(dd->dd_pool, + dd->dd_phys->dd_head_dataset_obj, FTAG, &hds); if (err) return (err); /* new name better not be in use */ - err = dsl_dataset_snap_lookup(mos, hds->ds_phys->ds_flags, - hds->ds_phys->ds_snapnames_zapobj, newsnapname, &val); - dsl_dataset_close(hds, DS_MODE_NONE, FTAG); + err = dsl_dataset_snap_lookup(hds, newsnapname, &val); + dsl_dataset_rele(hds, FTAG); if (err == 0) err = EEXIST; @@ -1921,12 +2052,11 @@ dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, ASSERT(ds->ds_phys->ds_next_snap_obj != 0); - VERIFY(0 == dsl_dataset_open_obj(dd->dd_pool, - dd->dd_phys->dd_head_dataset_obj, NULL, DS_MODE_NONE, FTAG, &hds)); + VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool, + dd->dd_phys->dd_head_dataset_obj, FTAG, &hds)); VERIFY(0 == dsl_dataset_get_snapname(ds)); - err = dsl_dataset_snap_remove(mos, hds->ds_phys->ds_flags, - hds->ds_phys->ds_snapnames_zapobj, ds->ds_snapname, tx); + err = dsl_dataset_snap_remove(hds, ds->ds_snapname, tx); ASSERT3U(err, ==, 0); mutex_enter(&ds->ds_lock); (void) strcpy(ds->ds_snapname, newsnapname); @@ -1937,7 +2067,7 @@ dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, spa_history_internal_log(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx, cr, "dataset = %llu", ds->ds_object); - dsl_dataset_close(hds, DS_MODE_NONE, FTAG); + dsl_dataset_rele(hds, FTAG); } struct renamesnaparg { @@ -1963,30 +2093,28 @@ dsl_snapshot_rename_one(char *name, void *arg) * For recursive snapshot renames the parent won't be changing * so we just pass name for both the to/from argument. */ - if (err = zfs_secpolicy_rename_perms(name, name, CRED())) { - (void) strcpy(ra->failed, name); - return (err); - } - - err = dsl_dataset_open(name, DS_MODE_READONLY | DS_MODE_STANDARD, - ra->dstg, &ds); + err = zfs_secpolicy_rename_perms(name, name, CRED()); if (err == ENOENT) { - *cp = '\0'; return (0); - } - if (err) { + } else if (err) { (void) strcpy(ra->failed, name); - *cp = '\0'; - dsl_dataset_close(ds, DS_MODE_STANDARD, ra->dstg); return (err); } #ifdef _KERNEL - /* for all filesystems undergoing rename, we'll need to unmount it */ + /* + * For all filesystems undergoing rename, we'll need to unmount it. + */ (void) zfs_unmount_snap(name, NULL); #endif - + err = dsl_dataset_hold(name, ra->dstg, &ds); *cp = '\0'; + if (err == ENOENT) { + return (0); + } else if (err) { + (void) strcpy(ra->failed, name); + return (err); + } dsl_sync_task_create(ra->dstg, dsl_dataset_snapshot_rename_check, dsl_dataset_snapshot_rename_sync, ds, ra->newsnap, 0); @@ -2036,7 +2164,7 @@ dsl_recursive_rename(char *oldname, const char *newname) (void) strcat(ra->failed, "@"); (void) strcat(ra->failed, ra->newsnap); } - dsl_dataset_close(ds, DS_MODE_STANDARD, ra->dstg); + dsl_dataset_rele(ds, ra->dstg); } if (err) @@ -2061,8 +2189,7 @@ dsl_valid_rename(char *oldname, void *arg) #pragma weak dmu_objset_rename = dsl_dataset_rename int -dsl_dataset_rename(char *oldname, const char *newname, - boolean_t recursive) +dsl_dataset_rename(char *oldname, const char *newname, boolean_t recursive) { dsl_dir_t *dd; dsl_dataset_t *ds; @@ -2075,7 +2202,7 @@ dsl_dataset_rename(char *oldname, const char *newname, if (tail == NULL) { int delta = strlen(newname) - strlen(oldname); - /* if we're growing, validate child size lengths */ + /* if we're growing, validate child name lengths */ if (delta > 0) err = dmu_objset_find(oldname, dsl_valid_rename, &delta, DS_FIND_CHILDREN | DS_FIND_SNAPSHOTS); @@ -2104,8 +2231,7 @@ dsl_dataset_rename(char *oldname, const char *newname, if (recursive) { err = dsl_recursive_rename(oldname, newname); } else { - err = dsl_dataset_open(oldname, - DS_MODE_READONLY | DS_MODE_STANDARD, FTAG, &ds); + err = dsl_dataset_hold(oldname, FTAG, &ds); if (err) return (err); @@ -2113,157 +2239,149 @@ dsl_dataset_rename(char *oldname, const char *newname, dsl_dataset_snapshot_rename_check, dsl_dataset_snapshot_rename_sync, ds, (char *)tail, 1); - dsl_dataset_close(ds, DS_MODE_STANDARD, FTAG); + dsl_dataset_rele(ds, FTAG); } return (err); } -struct promotearg { - uint64_t used, comp, uncomp, unique; - uint64_t ds_flags, newnext_obj, snapnames_obj; +struct promotenode { + list_node_t link; + dsl_dataset_t *ds; }; +struct promotearg { + list_t shared_snaps, origin_snaps, clone_snaps; + dsl_dataset_t *origin_origin, *origin_head; + uint64_t used, comp, uncomp, unique, cloneusedsnap, originusedsnap; +}; + +static int snaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep); + /* ARGSUSED */ static int dsl_dataset_promote_check(void *arg1, void *arg2, dmu_tx_t *tx) { dsl_dataset_t *hds = arg1; struct promotearg *pa = arg2; - dsl_dir_t *dd = hds->ds_dir; - dsl_pool_t *dp = hds->ds_dir->dd_pool; - dsl_dir_t *odd = NULL; - dsl_dataset_t *ds = NULL; - dsl_dataset_t *origin_ds = NULL; - dsl_dataset_t *newnext_ds = NULL; + struct promotenode *snap = list_head(&pa->shared_snaps); + dsl_dataset_t *origin_ds = snap->ds; int err; - char *name = NULL; - uint64_t itor = 0; - blkptr_t bp; - bzero(pa, sizeof (*pa)); - - /* Check that it is a clone */ - if (dd->dd_phys->dd_origin_obj == 0) + /* Check that it is a real clone */ + if (!dsl_dir_is_clone(hds->ds_dir)) return (EINVAL); /* Since this is so expensive, don't do the preliminary check */ if (!dmu_tx_is_syncing(tx)) return (0); - if (err = dsl_dataset_open_obj(dp, dd->dd_phys->dd_origin_obj, - NULL, DS_MODE_EXCLUSIVE, FTAG, &origin_ds)) - goto out; - odd = origin_ds->ds_dir; - - { - dsl_dataset_t *phds; - if (err = dsl_dataset_open_obj(dd->dd_pool, - odd->dd_phys->dd_head_dataset_obj, - NULL, DS_MODE_NONE, FTAG, &phds)) - goto out; - pa->ds_flags = phds->ds_phys->ds_flags; - pa->snapnames_obj = phds->ds_phys->ds_snapnames_zapobj; - dsl_dataset_close(phds, DS_MODE_NONE, FTAG); - } - - if (hds->ds_phys->ds_flags & DS_FLAG_NOPROMOTE) { - err = EXDEV; - goto out; - } - - /* find origin's new next ds */ - VERIFY(0 == dsl_dataset_open_obj(dd->dd_pool, hds->ds_object, - NULL, DS_MODE_NONE, FTAG, &newnext_ds)); - while (newnext_ds->ds_phys->ds_prev_snap_obj != origin_ds->ds_object) { - dsl_dataset_t *prev; - - if (err = dsl_dataset_open_obj(dd->dd_pool, - newnext_ds->ds_phys->ds_prev_snap_obj, - NULL, DS_MODE_NONE, FTAG, &prev)) - goto out; - dsl_dataset_close(newnext_ds, DS_MODE_NONE, FTAG); - newnext_ds = prev; - } - pa->newnext_obj = newnext_ds->ds_object; + if (hds->ds_phys->ds_flags & DS_FLAG_NOPROMOTE) + return (EXDEV); /* compute origin's new unique space */ - while ((err = bplist_iterate(&newnext_ds->ds_deadlist, - &itor, &bp)) == 0) { - if (bp.blk_birth > origin_ds->ds_phys->ds_prev_snap_txg) - pa->unique += bp_get_dasize(dd->dd_pool->dp_spa, &bp); - } - if (err != ENOENT) - goto out; + snap = list_tail(&pa->clone_snaps); + ASSERT3U(snap->ds->ds_phys->ds_prev_snap_obj, ==, origin_ds->ds_object); + err = bplist_space_birthrange(&snap->ds->ds_deadlist, + origin_ds->ds_phys->ds_prev_snap_txg, UINT64_MAX, &pa->unique); + if (err) + return (err); - /* Walk the snapshots that we are moving */ - name = kmem_alloc(MAXPATHLEN, KM_SLEEP); - ds = origin_ds; - /* CONSTCOND */ - while (TRUE) { + /* + * Walk the snapshots that we are moving + * + * Compute space to transfer. Consider the incremental changes + * to used for each snapshot: + * (my used) = (prev's used) + (blocks born) - (blocks killed) + * So each snapshot gave birth to: + * (blocks born) = (my used) - (prev's used) + (blocks killed) + * So a sequence would look like: + * (uN - u(N-1) + kN) + ... + (u1 - u0 + k1) + (u0 - 0 + k0) + * Which simplifies to: + * uN + kN + kN-1 + ... + k1 + k0 + * Note however, if we stop before we reach the ORIGIN we get: + * uN + kN + kN-1 + ... + kM - uM-1 + */ + pa->used = origin_ds->ds_phys->ds_used_bytes; + pa->comp = origin_ds->ds_phys->ds_compressed_bytes; + pa->uncomp = origin_ds->ds_phys->ds_uncompressed_bytes; + for (snap = list_head(&pa->shared_snaps); snap; + snap = list_next(&pa->shared_snaps, snap)) { uint64_t val, dlused, dlcomp, dluncomp; - dsl_dataset_t *prev; + dsl_dataset_t *ds = snap->ds; /* Check that the snapshot name does not conflict */ - dsl_dataset_name(ds, name); - err = dsl_dataset_snap_lookup(dd->dd_pool->dp_meta_objset, - hds->ds_phys->ds_flags, hds->ds_phys->ds_snapnames_zapobj, - ds->ds_snapname, &val); - if (err != ENOENT) { - if (err == 0) - err = EEXIST; - goto out; - } + VERIFY(0 == dsl_dataset_get_snapname(ds)); + err = dsl_dataset_snap_lookup(hds, ds->ds_snapname, &val); + if (err == 0) + return (EEXIST); + if (err != ENOENT) + return (err); - /* - * compute space to transfer. Each snapshot gave birth to: - * (my used) - (prev's used) + (deadlist's used) - */ - pa->used += ds->ds_phys->ds_used_bytes; - pa->comp += ds->ds_phys->ds_compressed_bytes; - pa->uncomp += ds->ds_phys->ds_uncompressed_bytes; - - /* If we reach the first snapshot, we're done. */ + /* The very first snapshot does not have a deadlist */ if (ds->ds_phys->ds_prev_snap_obj == 0) - break; + continue; if (err = bplist_space(&ds->ds_deadlist, &dlused, &dlcomp, &dluncomp)) - goto out; - if (err = dsl_dataset_open_obj(dd->dd_pool, - ds->ds_phys->ds_prev_snap_obj, NULL, DS_MODE_EXCLUSIVE, - FTAG, &prev)) - goto out; - pa->used += dlused - prev->ds_phys->ds_used_bytes; - pa->comp += dlcomp - prev->ds_phys->ds_compressed_bytes; - pa->uncomp += dluncomp - prev->ds_phys->ds_uncompressed_bytes; + return (err); + pa->used += dlused; + pa->comp += dlcomp; + pa->uncomp += dluncomp; + } - /* - * We could be a clone of a clone. If we reach our - * parent's branch point, we're done. - */ - if (prev->ds_phys->ds_next_snap_obj != ds->ds_object) { - dsl_dataset_close(prev, DS_MODE_EXCLUSIVE, FTAG); - break; - } - if (ds != origin_ds) - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); - ds = prev; + /* + * If we are a clone of a clone then we never reached ORIGIN, + * so we need to subtract out the clone origin's used space. + */ + if (pa->origin_origin) { + pa->used -= pa->origin_origin->ds_phys->ds_used_bytes; + pa->comp -= pa->origin_origin->ds_phys->ds_compressed_bytes; + pa->uncomp -= pa->origin_origin->ds_phys->ds_uncompressed_bytes; } /* Check that there is enough space here */ - err = dsl_dir_transfer_possible(odd, dd, pa->used); + err = dsl_dir_transfer_possible(origin_ds->ds_dir, hds->ds_dir, + pa->used); + if (err) + return (err); -out: - if (ds && ds != origin_ds) - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); - if (origin_ds) - dsl_dataset_close(origin_ds, DS_MODE_EXCLUSIVE, FTAG); - if (newnext_ds) - dsl_dataset_close(newnext_ds, DS_MODE_NONE, FTAG); - if (name) - kmem_free(name, MAXPATHLEN); - return (err); + /* + * Compute the amounts of space that will be used by snapshots + * after the promotion (for both origin and clone). For each, + * it is the amount of space that will be on all of their + * deadlists (that was not born before their new origin). + */ + if (hds->ds_dir->dd_phys->dd_flags & DD_FLAG_USED_BREAKDOWN) { + uint64_t space; + + /* + * Note, typically this will not be a clone of a clone, + * so snap->ds->ds_origin_txg will be < TXG_INITIAL, so + * these snaplist_space() -> bplist_space_birthrange() + * calls will be fast because they do not have to + * iterate over all bps. + */ + snap = list_head(&pa->origin_snaps); + err = snaplist_space(&pa->shared_snaps, + snap->ds->ds_origin_txg, &pa->cloneusedsnap); + if (err) + return (err); + + err = snaplist_space(&pa->clone_snaps, + snap->ds->ds_origin_txg, &space); + if (err) + return (err); + pa->cloneusedsnap += space; + } + if (origin_ds->ds_dir->dd_phys->dd_flags & DD_FLAG_USED_BREAKDOWN) { + err = snaplist_space(&pa->origin_snaps, + origin_ds->ds_phys->ds_creation_txg, &pa->originusedsnap); + if (err) + return (err); + } + + return (0); } static void @@ -2271,17 +2389,20 @@ dsl_dataset_promote_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) { dsl_dataset_t *hds = arg1; struct promotearg *pa = arg2; + struct promotenode *snap = list_head(&pa->shared_snaps); + dsl_dataset_t *origin_ds = snap->ds; + dsl_dataset_t *origin_head; dsl_dir_t *dd = hds->ds_dir; dsl_pool_t *dp = hds->ds_dir->dd_pool; dsl_dir_t *odd = NULL; - dsl_dataset_t *ds, *origin_ds; - char *name; + uint64_t oldnext_obj; + int64_t delta; - ASSERT(dd->dd_phys->dd_origin_obj != 0); ASSERT(0 == (hds->ds_phys->ds_flags & DS_FLAG_NOPROMOTE)); - VERIFY(0 == dsl_dataset_open_obj(dp, dd->dd_phys->dd_origin_obj, - NULL, DS_MODE_EXCLUSIVE, FTAG, &origin_ds)); + snap = list_head(&pa->origin_snaps); + origin_head = snap->ds; + /* * We need to explicitly open odd, since origin_ds's dd will be * changing. @@ -2289,21 +2410,49 @@ dsl_dataset_promote_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) VERIFY(0 == dsl_dir_open_obj(dp, origin_ds->ds_dir->dd_object, NULL, FTAG, &odd)); - /* move snapshots to this dir */ - name = kmem_alloc(MAXPATHLEN, KM_SLEEP); - ds = origin_ds; - /* CONSTCOND */ - while (TRUE) { - dsl_dataset_t *prev; + /* change origin's next snap */ + dmu_buf_will_dirty(origin_ds->ds_dbuf, tx); + oldnext_obj = origin_ds->ds_phys->ds_next_snap_obj; + snap = list_tail(&pa->clone_snaps); + ASSERT3U(snap->ds->ds_phys->ds_prev_snap_obj, ==, origin_ds->ds_object); + origin_ds->ds_phys->ds_next_snap_obj = snap->ds->ds_object; + /* change the origin's next clone */ + if (origin_ds->ds_phys->ds_next_clones_obj) { + VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset, + origin_ds->ds_phys->ds_next_clones_obj, + origin_ds->ds_phys->ds_next_snap_obj, tx)); + VERIFY3U(0, ==, zap_add_int(dp->dp_meta_objset, + origin_ds->ds_phys->ds_next_clones_obj, + oldnext_obj, tx)); + } + + /* change origin */ + dmu_buf_will_dirty(dd->dd_dbuf, tx); + ASSERT3U(dd->dd_phys->dd_origin_obj, ==, origin_ds->ds_object); + dd->dd_phys->dd_origin_obj = odd->dd_phys->dd_origin_obj; + hds->ds_origin_txg = origin_head->ds_origin_txg; + dmu_buf_will_dirty(odd->dd_dbuf, tx); + odd->dd_phys->dd_origin_obj = origin_ds->ds_object; + origin_head->ds_origin_txg = origin_ds->ds_phys->ds_creation_txg; + + /* move snapshots to this dir */ + for (snap = list_head(&pa->shared_snaps); snap; + snap = list_next(&pa->shared_snaps, snap)) { + dsl_dataset_t *ds = snap->ds; + + /* unregister props as dsl_dir is changing */ + if (ds->ds_user_ptr) { + ds->ds_user_evict_func(ds, ds->ds_user_ptr); + ds->ds_user_ptr = NULL; + } /* move snap name entry */ - dsl_dataset_name(ds, name); - VERIFY(0 == dsl_dataset_snap_remove(dp->dp_meta_objset, - pa->ds_flags, pa->snapnames_obj, ds->ds_snapname, tx)); + VERIFY(0 == dsl_dataset_get_snapname(ds)); + VERIFY(0 == dsl_dataset_snap_remove(origin_head, + ds->ds_snapname, tx)); VERIFY(0 == zap_add(dp->dp_meta_objset, hds->ds_phys->ds_snapnames_zapobj, ds->ds_snapname, 8, 1, &ds->ds_object, tx)); - /* change containing dsl_dir */ dmu_buf_will_dirty(ds->ds_dbuf, tx); ASSERT3U(ds->ds_phys->ds_dir_obj, ==, odd->dd_object); @@ -2314,78 +2463,219 @@ dsl_dataset_promote_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) NULL, ds, &ds->ds_dir)); ASSERT3U(dsl_prop_numcb(ds), ==, 0); - - if (ds->ds_phys->ds_prev_snap_obj == 0) - break; - - VERIFY(0 == dsl_dataset_open_obj(dp, - ds->ds_phys->ds_prev_snap_obj, NULL, DS_MODE_EXCLUSIVE, - FTAG, &prev)); - - if (prev->ds_phys->ds_next_snap_obj != ds->ds_object) { - dsl_dataset_close(prev, DS_MODE_EXCLUSIVE, FTAG); - break; - } - if (ds != origin_ds) - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); - ds = prev; } - if (ds != origin_ds) - dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); - /* change origin's next snap */ - dmu_buf_will_dirty(origin_ds->ds_dbuf, tx); - origin_ds->ds_phys->ds_next_snap_obj = pa->newnext_obj; + /* + * Change space accounting. + * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either + * both be valid, or both be 0 (resulting in delta == 0). This + * is true for each of {clone,origin} independently. + */ - /* change origin */ - dmu_buf_will_dirty(dd->dd_dbuf, tx); - ASSERT3U(dd->dd_phys->dd_origin_obj, ==, origin_ds->ds_object); - dd->dd_phys->dd_origin_obj = odd->dd_phys->dd_origin_obj; - dmu_buf_will_dirty(odd->dd_dbuf, tx); - odd->dd_phys->dd_origin_obj = origin_ds->ds_object; + delta = pa->cloneusedsnap - + dd->dd_phys->dd_used_breakdown[DD_USED_SNAP]; + ASSERT3S(delta, >=, 0); + ASSERT3U(pa->used, >=, delta); + dsl_dir_diduse_space(dd, DD_USED_SNAP, delta, 0, 0, tx); + dsl_dir_diduse_space(dd, DD_USED_HEAD, + pa->used - delta, pa->comp, pa->uncomp, tx); + + delta = pa->originusedsnap - + odd->dd_phys->dd_used_breakdown[DD_USED_SNAP]; + ASSERT3S(delta, <=, 0); + ASSERT3U(pa->used, >=, -delta); + dsl_dir_diduse_space(odd, DD_USED_SNAP, delta, 0, 0, tx); + dsl_dir_diduse_space(odd, DD_USED_HEAD, + -pa->used - delta, -pa->comp, -pa->uncomp, tx); - /* change space accounting */ - dsl_dir_diduse_space(odd, -pa->used, -pa->comp, -pa->uncomp, tx); - dsl_dir_diduse_space(dd, pa->used, pa->comp, pa->uncomp, tx); origin_ds->ds_phys->ds_unique_bytes = pa->unique; /* log history record */ spa_history_internal_log(LOG_DS_PROMOTE, dd->dd_pool->dp_spa, tx, - cr, "dataset = %llu", ds->ds_object); + cr, "dataset = %llu", hds->ds_object); dsl_dir_close(odd, FTAG); - dsl_dataset_close(origin_ds, DS_MODE_EXCLUSIVE, FTAG); - kmem_free(name, MAXPATHLEN); } +static char *snaplist_tag = "snaplist"; +/* + * Make a list of dsl_dataset_t's for the snapshots between first_obj + * (exclusive) and last_obj (inclusive). The list will be in reverse + * order (last_obj will be the list_head()). If first_obj == 0, do all + * snapshots back to this dataset's origin. + */ +static int +snaplist_make(dsl_pool_t *dp, boolean_t own, + uint64_t first_obj, uint64_t last_obj, list_t *l) +{ + uint64_t obj = last_obj; + + ASSERT(RW_LOCK_HELD(&dp->dp_config_rwlock)); + + list_create(l, sizeof (struct promotenode), + offsetof(struct promotenode, link)); + + while (obj != first_obj) { + dsl_dataset_t *ds; + struct promotenode *snap; + int err; + + if (own) { + err = dsl_dataset_own_obj(dp, obj, + 0, snaplist_tag, &ds); + if (err == 0) + dsl_dataset_make_exclusive(ds, snaplist_tag); + } else { + err = dsl_dataset_hold_obj(dp, obj, snaplist_tag, &ds); + } + if (err == ENOENT) { + /* lost race with snapshot destroy */ + struct promotenode *last = list_tail(l); + ASSERT(obj != last->ds->ds_phys->ds_prev_snap_obj); + obj = last->ds->ds_phys->ds_prev_snap_obj; + continue; + } else if (err) { + return (err); + } + + if (first_obj == 0) + first_obj = ds->ds_dir->dd_phys->dd_origin_obj; + + snap = kmem_alloc(sizeof (struct promotenode), KM_SLEEP); + snap->ds = ds; + list_insert_tail(l, snap); + obj = ds->ds_phys->ds_prev_snap_obj; + } + + return (0); +} + +static int +snaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep) +{ + struct promotenode *snap; + + *spacep = 0; + for (snap = list_head(l); snap; snap = list_next(l, snap)) { + uint64_t used; + int err = bplist_space_birthrange(&snap->ds->ds_deadlist, + mintxg, UINT64_MAX, &used); + if (err) + return (err); + *spacep += used; + } + return (0); +} + +static void +snaplist_destroy(list_t *l, boolean_t own) +{ + struct promotenode *snap; + + if (!list_link_active(&l->list_head)) + return; + + while ((snap = list_tail(l)) != NULL) { + list_remove(l, snap); + if (own) + dsl_dataset_disown(snap->ds, snaplist_tag); + else + dsl_dataset_rele(snap->ds, snaplist_tag); + kmem_free(snap, sizeof (struct promotenode)); + } + list_destroy(l); +} + +/* + * Promote a clone. Nomenclature note: + * "clone" or "cds": the original clone which is being promoted + * "origin" or "ods": the snapshot which is originally clone's origin + * "origin head" or "ohds": the dataset which is the head + * (filesystem/volume) for the origin + * "origin origin": the origin of the origin's filesystem (typically + * NULL, indicating that the clone is not a clone of a clone). + */ int dsl_dataset_promote(const char *name) { dsl_dataset_t *ds; - int err; + dsl_dir_t *dd; + dsl_pool_t *dp; dmu_object_info_t doi; - struct promotearg pa; + struct promotearg pa = { 0 }; + struct promotenode *snap; + int err; - err = dsl_dataset_open(name, DS_MODE_NONE, FTAG, &ds); + err = dsl_dataset_hold(name, FTAG, &ds); if (err) return (err); + dd = ds->ds_dir; + dp = dd->dd_pool; - err = dmu_object_info(ds->ds_dir->dd_pool->dp_meta_objset, + err = dmu_object_info(dp->dp_meta_objset, ds->ds_phys->ds_snapnames_zapobj, &doi); if (err) { - dsl_dataset_close(ds, DS_MODE_NONE, FTAG); + dsl_dataset_rele(ds, FTAG); return (err); } + if (dsl_dataset_is_snapshot(ds) || dd->dd_phys->dd_origin_obj == 0) { + dsl_dataset_rele(ds, FTAG); + return (EINVAL); + } + + /* + * We are going to inherit all the snapshots taken before our + * origin (i.e., our new origin will be our parent's origin). + * Take ownership of them so that we can rename them into our + * namespace. + */ + rw_enter(&dp->dp_config_rwlock, RW_READER); + + err = snaplist_make(dp, B_TRUE, 0, dd->dd_phys->dd_origin_obj, + &pa.shared_snaps); + if (err != 0) + goto out; + + err = snaplist_make(dp, B_FALSE, 0, ds->ds_object, &pa.clone_snaps); + if (err != 0) + goto out; + + snap = list_head(&pa.shared_snaps); + ASSERT3U(snap->ds->ds_object, ==, dd->dd_phys->dd_origin_obj); + err = snaplist_make(dp, B_FALSE, dd->dd_phys->dd_origin_obj, + snap->ds->ds_dir->dd_phys->dd_head_dataset_obj, &pa.origin_snaps); + if (err != 0) + goto out; + + if (dsl_dir_is_clone(snap->ds->ds_dir)) { + err = dsl_dataset_own_obj(dp, + snap->ds->ds_dir->dd_phys->dd_origin_obj, + 0, FTAG, &pa.origin_origin); + if (err != 0) + goto out; + } + +out: + rw_exit(&dp->dp_config_rwlock); + /* * Add in 128x the snapnames zapobj size, since we will be moving * a bunch of snapnames to the promoted ds, and dirtying their * bonus buffers. */ - err = dsl_sync_task_do(ds->ds_dir->dd_pool, - dsl_dataset_promote_check, - dsl_dataset_promote_sync, ds, &pa, 2 + 2 * doi.doi_physical_blks); - dsl_dataset_close(ds, DS_MODE_NONE, FTAG); + if (err == 0) { + err = dsl_sync_task_do(dp, dsl_dataset_promote_check, + dsl_dataset_promote_sync, ds, &pa, + 2 + 2 * doi.doi_physical_blks); + } + + snaplist_destroy(&pa.shared_snaps, B_TRUE); + snaplist_destroy(&pa.clone_snaps, B_FALSE); + snaplist_destroy(&pa.origin_snaps, B_FALSE); + if (pa.origin_origin) + dsl_dataset_disown(pa.origin_origin, FTAG); + dsl_dataset_rele(ds, FTAG); return (err); } @@ -2445,10 +2735,6 @@ dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) { struct cloneswaparg *csa = arg1; dsl_pool_t *dp = csa->cds->ds_dir->dd_pool; - uint64_t itor = 0; - blkptr_t bp; - uint64_t unique = 0; - int err; ASSERT(csa->cds->ds_reserved == 0); ASSERT(csa->cds->ds_quota == csa->ohds->ds_quota); @@ -2468,16 +2754,10 @@ dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) csa->ohds->ds_user_ptr = NULL; } - /* compute unique space */ - while ((err = bplist_iterate(&csa->cds->ds_deadlist, - &itor, &bp)) == 0) { - if (bp.blk_birth > csa->cds->ds_prev->ds_phys->ds_prev_snap_txg) - unique += bp_get_dasize(dp->dp_spa, &bp); - } - VERIFY(err == ENOENT); - /* reset origin's unique bytes */ - csa->cds->ds_prev->ds_phys->ds_unique_bytes = unique; + VERIFY(0 == bplist_space_birthrange(&csa->cds->ds_deadlist, + csa->cds->ds_prev->ds_phys->ds_prev_snap_txg, UINT64_MAX, + &csa->cds->ds_prev->ds_phys->ds_unique_bytes)); /* swap blkptrs */ { @@ -2493,10 +2773,14 @@ dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) uint64_t cdl_used, cdl_comp, cdl_uncomp; uint64_t odl_used, odl_comp, odl_uncomp; + ASSERT3U(csa->cds->ds_dir->dd_phys-> + dd_used_breakdown[DD_USED_SNAP], ==, 0); + VERIFY(0 == bplist_space(&csa->cds->ds_deadlist, &cdl_used, &cdl_comp, &cdl_uncomp)); VERIFY(0 == bplist_space(&csa->ohds->ds_deadlist, &odl_used, &odl_comp, &odl_uncomp)); + dused = csa->cds->ds_phys->ds_used_bytes + cdl_used - (csa->ohds->ds_phys->ds_used_bytes + odl_used); dcomp = csa->cds->ds_phys->ds_compressed_bytes + cdl_comp - @@ -2505,10 +2789,23 @@ dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) cdl_uncomp - (csa->ohds->ds_phys->ds_uncompressed_bytes + odl_uncomp); - dsl_dir_diduse_space(csa->ohds->ds_dir, + dsl_dir_diduse_space(csa->ohds->ds_dir, DD_USED_HEAD, dused, dcomp, duncomp, tx); - dsl_dir_diduse_space(csa->cds->ds_dir, + dsl_dir_diduse_space(csa->cds->ds_dir, DD_USED_HEAD, -dused, -dcomp, -duncomp, tx); + + /* + * The difference in the space used by snapshots is the + * difference in snapshot space due to the head's + * deadlist (since that's the only thing that's + * changing that affects the snapused). + */ + VERIFY(0 == bplist_space_birthrange(&csa->cds->ds_deadlist, + csa->ohds->ds_origin_txg, UINT64_MAX, &cdl_used)); + VERIFY(0 == bplist_space_birthrange(&csa->ohds->ds_deadlist, + csa->ohds->ds_origin_txg, UINT64_MAX, &odl_used)); + dsl_dir_transfer_space(csa->ohds->ds_dir, cdl_used - odl_used, + DD_USED_HEAD, DD_USED_SNAP, tx); } #define SWITCH64(x, y) \ @@ -2529,8 +2826,8 @@ dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) csa->cds->ds_phys->ds_unique_bytes); /* apply any parent delta for change in unconsumed refreservation */ - dsl_dir_diduse_space(csa->ohds->ds_dir, csa->unused_refres_delta, - 0, 0, tx); + dsl_dir_diduse_space(csa->ohds->ds_dir, DD_USED_REFRSRV, + csa->unused_refres_delta, 0, 0, tx); /* swap deadlists */ bplist_close(&csa->cds->ds_deadlist); @@ -2541,26 +2838,41 @@ dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) csa->cds->ds_phys->ds_deadlist_obj)); VERIFY(0 == bplist_open(&csa->ohds->ds_deadlist, dp->dp_meta_objset, csa->ohds->ds_phys->ds_deadlist_obj)); + + dsl_pool_ds_clone_swapped(csa->ohds, csa->cds, tx); } /* - * Swap 'clone' with its origin head file system. + * Swap 'clone' with its origin head file system. Used at the end + * of "online recv" to swizzle the file system to the new version. */ int dsl_dataset_clone_swap(dsl_dataset_t *clone, dsl_dataset_t *origin_head, boolean_t force) { struct cloneswaparg csa; + int error; - ASSERT(clone->ds_open_refcount == DS_REF_MAX); - ASSERT(origin_head->ds_open_refcount == DS_REF_MAX); - + ASSERT(clone->ds_owner); + ASSERT(origin_head->ds_owner); +retry: + /* Need exclusive access for the swap */ + rw_enter(&clone->ds_rwlock, RW_WRITER); + if (!rw_tryenter(&origin_head->ds_rwlock, RW_WRITER)) { + rw_exit(&clone->ds_rwlock); + rw_enter(&origin_head->ds_rwlock, RW_WRITER); + if (!rw_tryenter(&clone->ds_rwlock, RW_WRITER)) { + rw_exit(&origin_head->ds_rwlock); + goto retry; + } + } csa.cds = clone; csa.ohds = origin_head; csa.force = force; - return (dsl_sync_task_do(clone->ds_dir->dd_pool, + error = dsl_sync_task_do(clone->ds_dir->dd_pool, dsl_dataset_clone_swap_check, - dsl_dataset_clone_swap_sync, &csa, NULL, 9)); + dsl_dataset_clone_swap_sync, &csa, NULL, 9); + return (error); } /* @@ -2572,31 +2884,26 @@ dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf) { spa_t *spa; dsl_pool_t *dp; - dsl_dataset_t *ds = NULL; + dsl_dataset_t *ds; int error; if ((error = spa_open(pname, &spa, FTAG)) != 0) return (error); dp = spa_get_dsl(spa); rw_enter(&dp->dp_config_rwlock, RW_READER); - if ((error = dsl_dataset_open_obj(dp, obj, - NULL, DS_MODE_NONE, FTAG, &ds)) != 0) { - rw_exit(&dp->dp_config_rwlock); - spa_close(spa, FTAG); - return (error); + if ((error = dsl_dataset_hold_obj(dp, obj, FTAG, &ds)) == 0) { + dsl_dataset_name(ds, buf); + dsl_dataset_rele(ds, FTAG); } - dsl_dataset_name(ds, buf); - dsl_dataset_close(ds, DS_MODE_NONE, FTAG); rw_exit(&dp->dp_config_rwlock); spa_close(spa, FTAG); - return (0); + return (error); } int dsl_dataset_check_quota(dsl_dataset_t *ds, boolean_t check_quota, - uint64_t asize, uint64_t inflight, uint64_t *used, - uint64_t *ref_rsrv) + uint64_t asize, uint64_t inflight, uint64_t *used, uint64_t *ref_rsrv) { int error = 0; @@ -2672,15 +2979,13 @@ dsl_dataset_set_quota_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) dmu_buf_will_dirty(ds->ds_dbuf, tx); - mutex_enter(&ds->ds_lock); ds->ds_quota = new_quota; - mutex_exit(&ds->ds_lock); dsl_prop_set_uint64_sync(ds->ds_dir, "refquota", new_quota, cr, tx); spa_history_internal_log(LOG_DS_REFQUOTA, ds->ds_dir->dd_pool->dp_spa, tx, cr, "%lld dataset = %llu ", - (longlong_t)new_quota, ds->ds_dir->dd_phys->dd_head_dataset_obj); + (longlong_t)new_quota, ds->ds_object); } int @@ -2689,7 +2994,7 @@ dsl_dataset_set_quota(const char *dsname, uint64_t quota) dsl_dataset_t *ds; int err; - err = dsl_dataset_open(dsname, DS_MODE_STANDARD, FTAG, &ds); + err = dsl_dataset_hold(dsname, FTAG, &ds); if (err) return (err); @@ -2704,7 +3009,7 @@ dsl_dataset_set_quota(const char *dsname, uint64_t quota) dsl_dataset_set_quota_check, dsl_dataset_set_quota_sync, ds, "a, 0); } - dsl_dataset_close(ds, DS_MODE_STANDARD, FTAG); + dsl_dataset_rele(ds, FTAG); return (err); } @@ -2762,6 +3067,7 @@ dsl_dataset_set_reservation_sync(void *arg1, void *arg2, cred_t *cr, dmu_buf_will_dirty(ds->ds_dbuf, tx); + mutex_enter(&ds->ds_dir->dd_lock); mutex_enter(&ds->ds_lock); unique = dsl_dataset_unique(ds); delta = MAX(0, (int64_t)(new_reservation - unique)) - @@ -2769,15 +3075,14 @@ dsl_dataset_set_reservation_sync(void *arg1, void *arg2, cred_t *cr, ds->ds_reserved = new_reservation; mutex_exit(&ds->ds_lock); + dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx); + mutex_exit(&ds->ds_dir->dd_lock); dsl_prop_set_uint64_sync(ds->ds_dir, "refreservation", new_reservation, cr, tx); - dsl_dir_diduse_space(ds->ds_dir, delta, 0, 0, tx); - spa_history_internal_log(LOG_DS_REFRESERV, ds->ds_dir->dd_pool->dp_spa, tx, cr, "%lld dataset = %llu", - (longlong_t)new_reservation, - ds->ds_dir->dd_phys->dd_head_dataset_obj); + (longlong_t)new_reservation, ds->ds_object); } int @@ -2786,13 +3091,13 @@ dsl_dataset_set_reservation(const char *dsname, uint64_t reservation) dsl_dataset_t *ds; int err; - err = dsl_dataset_open(dsname, DS_MODE_STANDARD, FTAG, &ds); + err = dsl_dataset_hold(dsname, FTAG, &ds); if (err) return (err); err = dsl_sync_task_do(ds->ds_dir->dd_pool, dsl_dataset_set_reservation_check, dsl_dataset_set_reservation_sync, ds, &reservation, 0); - dsl_dataset_close(ds, DS_MODE_STANDARD, FTAG); + dsl_dataset_rele(ds, FTAG); return (err); } diff --git a/zfs/lib/libzpool/dsl_deleg.c b/zfs/lib/libzpool/dsl_deleg.c index bb386c13a..da5d15787 100644 --- a/zfs/lib/libzpool/dsl_deleg.c +++ b/zfs/lib/libzpool/dsl_deleg.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -66,7 +66,7 @@ * The ZAP OBJ is referred to as the jump object. */ -#pragma ident "@(#)dsl_deleg.c 1.5 07/10/29 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -533,42 +533,33 @@ dsl_load_user_sets(objset_t *mos, uint64_t zapobj, avl_tree_t *avl, * Check if user has requested permission. */ int -dsl_deleg_access(const char *ddname, const char *perm, cred_t *cr) +dsl_deleg_access(const char *dsname, const char *perm, cred_t *cr) { - dsl_dir_t *dd, *startdd; + dsl_dataset_t *ds; + dsl_dir_t *dd; dsl_pool_t *dp; void *cookie; int error; char checkflag = ZFS_DELEG_LOCAL; - const char *tail; objset_t *mos; avl_tree_t permsets; perm_set_t *setnode; - /* - * Use tail so that zfs_ioctl() code doesn't have - * to always to to figure out parent name in order - * to do access check. for example renaming a snapshot - */ - error = dsl_dir_open(ddname, FTAG, &startdd, &tail); + error = dsl_dataset_hold(dsname, FTAG, &ds); if (error) return (error); - if (tail && tail[0] != '@') { - dsl_dir_close(startdd, FTAG); - return (ENOENT); - } - dp = startdd->dd_pool; + dp = ds->ds_dir->dd_pool; mos = dp->dp_meta_objset; if (dsl_delegation_on(mos) == B_FALSE) { - dsl_dir_close(startdd, FTAG); + dsl_dataset_rele(ds, FTAG); return (ECANCELED); } if (spa_version(dmu_objset_spa(dp->dp_meta_objset)) < SPA_VERSION_DELEGATED_PERMS) { - dsl_dir_close(startdd, FTAG); + dsl_dataset_rele(ds, FTAG); return (EPERM); } @@ -576,7 +567,7 @@ dsl_deleg_access(const char *ddname, const char *perm, cred_t *cr) offsetof(perm_set_t, p_node)); rw_enter(&dp->dp_config_rwlock, RW_READER); - for (dd = startdd; dd != NULL; dd = dd->dd_parent, + for (dd = ds->ds_dir; dd != NULL; dd = dd->dd_parent, checkflag = ZFS_DELEG_DESCENDENT) { uint64_t zapobj; boolean_t expanded; @@ -588,7 +579,7 @@ dsl_deleg_access(const char *ddname, const char *perm, cred_t *cr) if (!INGLOBALZONE(curproc)) { uint64_t zoned; - if (dsl_prop_get_ds_locked(dd, + if (dsl_prop_get_dd(dd, zfs_prop_to_name(ZFS_PROP_ZONED), 8, 1, &zoned, NULL) != 0) break; @@ -637,7 +628,7 @@ again: error = EPERM; success: rw_exit(&dp->dp_config_rwlock); - dsl_dir_close(startdd, FTAG); + dsl_dataset_rele(ds, FTAG); cookie = NULL; while ((setnode = avl_destroy_nodes(&permsets, &cookie)) != NULL) diff --git a/zfs/lib/libzpool/dsl_dir.c b/zfs/lib/libzpool/dsl_dir.c index fac1664c3..48d87f97f 100644 --- a/zfs/lib/libzpool/dsl_dir.c +++ b/zfs/lib/libzpool/dsl_dir.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dsl_dir.c 1.25 08/03/25 SMI" - #include #include #include @@ -59,8 +57,6 @@ dsl_dir_evict(dmu_buf_t *db, void *arg) ASSERT(dd->dd_space_towrite[t] == 0); } - ASSERT3U(dd->dd_used_bytes, ==, dd->dd_phys->dd_used_bytes); - if (dd->dd_parent) dsl_dir_close(dd->dd_parent, dd); @@ -95,9 +91,9 @@ dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, dmu_object_info_t doi; dmu_object_info_from_db(dbuf, &doi); ASSERT3U(doi.doi_type, ==, DMU_OT_DSL_DIR); + ASSERT3U(doi.doi_bonus_size, >=, sizeof (dsl_dir_phys_t)); } #endif - /* XXX assert bonus buffer size is correct */ if (dd == NULL) { dsl_dir_t *winner; int err; @@ -107,7 +103,6 @@ dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, dd->dd_dbuf = dbuf; dd->dd_pool = dp; dd->dd_phys = dbuf->db_data; - dd->dd_used_bytes = dd->dd_phys->dd_used_bytes; mutex_init(&dd->dd_lock, NULL, MUTEX_DEFAULT, NULL); list_create(&dd->dd_prop_cbs, sizeof (dsl_prop_cb_record_t), @@ -116,12 +111,8 @@ dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, if (dd->dd_phys->dd_parent_obj) { err = dsl_dir_open_obj(dp, dd->dd_phys->dd_parent_obj, NULL, dd, &dd->dd_parent); - if (err) { - mutex_destroy(&dd->dd_lock); - kmem_free(dd, sizeof (dsl_dir_t)); - dmu_buf_rele(dbuf, tag); - return (err); - } + if (err) + goto errout; if (tail) { #ifdef ZFS_DEBUG uint64_t foundobj; @@ -137,13 +128,8 @@ dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, dd->dd_parent->dd_phys->dd_child_dir_zapobj, ddobj, 0, dd->dd_myname); } - if (err) { - dsl_dir_close(dd->dd_parent, dd); - mutex_destroy(&dd->dd_lock); - kmem_free(dd, sizeof (dsl_dir_t)); - dmu_buf_rele(dbuf, tag); - return (err); - } + if (err) + goto errout; } else { (void) strcpy(dd->dd_myname, spa_name(dp->dp_spa)); } @@ -176,6 +162,15 @@ dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, ASSERT3P(dd->dd_dbuf, ==, dbuf); *ddp = dd; return (0); + +errout: + if (dd->dd_parent) + dsl_dir_close(dd->dd_parent, dd); + mutex_destroy(&dd->dd_lock); + kmem_free(dd, sizeof (dsl_dir_t)); + dmu_buf_rele(dbuf, tag); + return (err); + } void @@ -406,27 +401,37 @@ dsl_dir_open(const char *name, void *tag, dsl_dir_t **ddp, const char **tailp) } uint64_t -dsl_dir_create_sync(dsl_dir_t *pds, const char *name, dmu_tx_t *tx) +dsl_dir_create_sync(dsl_pool_t *dp, dsl_dir_t *pds, const char *name, + dmu_tx_t *tx) { - objset_t *mos = pds->dd_pool->dp_meta_objset; + objset_t *mos = dp->dp_meta_objset; uint64_t ddobj; dsl_dir_phys_t *dsphys; dmu_buf_t *dbuf; ddobj = dmu_object_alloc(mos, DMU_OT_DSL_DIR, 0, DMU_OT_DSL_DIR, sizeof (dsl_dir_phys_t), tx); - VERIFY(0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, - name, sizeof (uint64_t), 1, &ddobj, tx)); + if (pds) { + VERIFY(0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, + name, sizeof (uint64_t), 1, &ddobj, tx)); + } else { + /* it's the root dir */ + VERIFY(0 == zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1, &ddobj, tx)); + } VERIFY(0 == dmu_bonus_hold(mos, ddobj, FTAG, &dbuf)); dmu_buf_will_dirty(dbuf, tx); dsphys = dbuf->db_data; dsphys->dd_creation_time = gethrestime_sec(); - dsphys->dd_parent_obj = pds->dd_object; + if (pds) + dsphys->dd_parent_obj = pds->dd_object; dsphys->dd_props_zapobj = zap_create(mos, DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx); dsphys->dd_child_dir_zapobj = zap_create(mos, DMU_OT_DSL_DIR_CHILD_MAP, DMU_OT_NONE, 0, tx); + if (spa_version(dp->dp_spa) >= SPA_VERSION_USED_BREAKDOWN) + dsphys->dd_flags |= DD_FLAG_USED_BREAKDOWN; dmu_buf_rele(dbuf, FTAG); return (ddobj); @@ -468,6 +473,7 @@ dsl_dir_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) dsl_dir_t *dd = arg1; objset_t *mos = dd->dd_pool->dp_meta_objset; uint64_t val, obj; + dd_used_t t; ASSERT(RW_WRITE_HELD(&dd->dd_pool->dp_config_rwlock)); ASSERT(dd->dd_phys->dd_head_dataset_obj == 0); @@ -475,8 +481,10 @@ dsl_dir_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) /* Remove our reservation. */ val = 0; dsl_dir_set_reservation_sync(dd, &val, cr, tx); - ASSERT3U(dd->dd_used_bytes, ==, 0); + ASSERT3U(dd->dd_phys->dd_used_bytes, ==, 0); ASSERT3U(dd->dd_phys->dd_reserved, ==, 0); + for (t = 0; t < DD_USED_NUM; t++) + ASSERT3U(dd->dd_phys->dd_used_breakdown[t], ==, 0); VERIFY(0 == zap_destroy(mos, dd->dd_phys->dd_child_dir_zapobj, tx)); VERIFY(0 == zap_destroy(mos, dd->dd_phys->dd_props_zapobj, tx)); @@ -489,38 +497,21 @@ dsl_dir_destroy_sync(void *arg1, void *tag, cred_t *cr, dmu_tx_t *tx) VERIFY(0 == dmu_object_free(mos, obj, tx)); } -void -dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx) +boolean_t +dsl_dir_is_clone(dsl_dir_t *dd) { - dsl_dir_phys_t *dsp; - dmu_buf_t *dbuf; - int error; - - *ddobjp = dmu_object_alloc(mos, DMU_OT_DSL_DIR, 0, - DMU_OT_DSL_DIR, sizeof (dsl_dir_phys_t), tx); - - error = zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ROOT_DATASET, - sizeof (uint64_t), 1, ddobjp, tx); - ASSERT3U(error, ==, 0); - - VERIFY(0 == dmu_bonus_hold(mos, *ddobjp, FTAG, &dbuf)); - dmu_buf_will_dirty(dbuf, tx); - dsp = dbuf->db_data; - - dsp->dd_creation_time = gethrestime_sec(); - dsp->dd_props_zapobj = zap_create(mos, - DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx); - dsp->dd_child_dir_zapobj = zap_create(mos, - DMU_OT_DSL_DIR_CHILD_MAP, DMU_OT_NONE, 0, tx); - - dmu_buf_rele(dbuf, FTAG); + return (dd->dd_phys->dd_origin_obj && + (dd->dd_pool->dp_origin_snap == NULL || + dd->dd_phys->dd_origin_obj != + dd->dd_pool->dp_origin_snap->ds_object)); } void dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv) { mutex_enter(&dd->dd_lock); - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, dd->dd_used_bytes); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, + dd->dd_phys->dd_used_bytes); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_QUOTA, dd->dd_phys->dd_quota); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_RESERVATION, dd->dd_phys->dd_reserved); @@ -528,18 +519,28 @@ dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv) dd->dd_phys->dd_compressed_bytes == 0 ? 100 : (dd->dd_phys->dd_uncompressed_bytes * 100 / dd->dd_phys->dd_compressed_bytes)); + if (dd->dd_phys->dd_flags & DD_FLAG_USED_BREAKDOWN) { + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDSNAP, + dd->dd_phys->dd_used_breakdown[DD_USED_SNAP]); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDDS, + dd->dd_phys->dd_used_breakdown[DD_USED_HEAD]); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDREFRESERV, + dd->dd_phys->dd_used_breakdown[DD_USED_REFRSRV]); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDCHILD, + dd->dd_phys->dd_used_breakdown[DD_USED_CHILD] + + dd->dd_phys->dd_used_breakdown[DD_USED_CHILD_RSRV]); + } mutex_exit(&dd->dd_lock); rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); - if (dd->dd_phys->dd_origin_obj) { + if (dsl_dir_is_clone(dd)) { dsl_dataset_t *ds; char buf[MAXNAMELEN]; - VERIFY(0 == dsl_dataset_open_obj(dd->dd_pool, - dd->dd_phys->dd_origin_obj, - NULL, DS_MODE_NONE, FTAG, &ds)); + VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool, + dd->dd_phys->dd_origin_obj, FTAG, &ds)); dsl_dataset_name(ds, buf); - dsl_dataset_close(ds, DS_MODE_NONE, FTAG); + dsl_dataset_rele(ds, FTAG); dsl_prop_nvlist_add_string(nv, ZFS_PROP_ORIGIN, buf); } rw_exit(&dd->dd_pool->dp_config_rwlock); @@ -578,7 +579,6 @@ dsl_dir_sync(dsl_dir_t *dd, dmu_tx_t *tx) dprintf_dd(dd, "txg=%llu towrite=%lluK\n", tx->tx_txg, dd->dd_space_towrite[tx->tx_txg&TXG_MASK] / 1024); dd->dd_space_towrite[tx->tx_txg&TXG_MASK] = 0; - dd->dd_phys->dd_used_bytes = dd->dd_used_bytes; mutex_exit(&dd->dd_lock); /* release the hold from dsl_dir_dirty */ @@ -626,11 +626,9 @@ dsl_dir_space_available(dsl_dir_t *dd, mutex_enter(&dd->dd_lock); if (dd->dd_phys->dd_quota != 0) quota = dd->dd_phys->dd_quota; - used = dd->dd_used_bytes; + used = dd->dd_phys->dd_used_bytes; if (!ondiskonly) used += dsl_dir_space_towrite(dd); - if (dd == ancestor) - used += delta; if (dd->dd_parent == NULL) { uint64_t poolsize = dsl_pool_adjustedsize(dd->dd_pool, FALSE); @@ -645,6 +643,14 @@ dsl_dir_space_available(dsl_dir_t *dd, parentspace += dd->dd_phys->dd_reserved - used; } + if (dd == ancestor) { + ASSERT(delta <= 0); + ASSERT(used >= -delta); + used += delta; + if (parentspace != UINT64_MAX) + parentspace -= delta; + } + if (used > quota) { /* over quota */ myspace = 0; @@ -702,7 +708,7 @@ dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree, est_inflight = dsl_dir_space_towrite(dd); for (i = 0; i < TXG_SIZE; i++) est_inflight += dd->dd_tempreserved[i]; - used_on_disk = dd->dd_used_bytes; + used_on_disk = dd->dd_phys->dd_used_bytes; /* * On the first iteration, fetch the dataset's used-on-disk and @@ -893,7 +899,7 @@ dsl_dir_willuse_space_impl(dsl_dir_t *dd, int64_t space, dmu_tx_t *tx) if (space > 0) dd->dd_space_towrite[tx->tx_txg & TXG_MASK] += space; - est_used = dsl_dir_space_towrite(dd) + dd->dd_used_bytes; + est_used = dsl_dir_space_towrite(dd) + dd->dd_phys->dd_used_bytes; parent_space = parent_delta(dd, est_used, space); mutex_exit(&dd->dd_lock); @@ -919,33 +925,79 @@ dsl_dir_willuse_space(dsl_dir_t *dd, int64_t space, dmu_tx_t *tx) /* call from syncing context when we actually write/free space for this dd */ void -dsl_dir_diduse_space(dsl_dir_t *dd, +dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type, int64_t used, int64_t compressed, int64_t uncompressed, dmu_tx_t *tx) { int64_t accounted_delta; + boolean_t needlock = !MUTEX_HELD(&dd->dd_lock); ASSERT(dmu_tx_is_syncing(tx)); + ASSERT(type < DD_USED_NUM); dsl_dir_dirty(dd, tx); - mutex_enter(&dd->dd_lock); - accounted_delta = parent_delta(dd, dd->dd_used_bytes, used); - ASSERT(used >= 0 || dd->dd_used_bytes >= -used); + if (needlock) + mutex_enter(&dd->dd_lock); + accounted_delta = parent_delta(dd, dd->dd_phys->dd_used_bytes, used); + ASSERT(used >= 0 || dd->dd_phys->dd_used_bytes >= -used); ASSERT(compressed >= 0 || dd->dd_phys->dd_compressed_bytes >= -compressed); ASSERT(uncompressed >= 0 || dd->dd_phys->dd_uncompressed_bytes >= -uncompressed); - dd->dd_used_bytes += used; + dd->dd_phys->dd_used_bytes += used; dd->dd_phys->dd_uncompressed_bytes += uncompressed; dd->dd_phys->dd_compressed_bytes += compressed; - mutex_exit(&dd->dd_lock); + + if (dd->dd_phys->dd_flags & DD_FLAG_USED_BREAKDOWN) { + ASSERT(used > 0 || + dd->dd_phys->dd_used_breakdown[type] >= -used); + dd->dd_phys->dd_used_breakdown[type] += used; +#ifdef DEBUG + dd_used_t t; + uint64_t u = 0; + for (t = 0; t < DD_USED_NUM; t++) + u += dd->dd_phys->dd_used_breakdown[t]; + ASSERT3U(u, ==, dd->dd_phys->dd_used_bytes); +#endif + } + if (needlock) + mutex_exit(&dd->dd_lock); if (dd->dd_parent != NULL) { - dsl_dir_diduse_space(dd->dd_parent, + dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD, accounted_delta, compressed, uncompressed, tx); + dsl_dir_transfer_space(dd->dd_parent, + used - accounted_delta, + DD_USED_CHILD_RSRV, DD_USED_CHILD, tx); } } +void +dsl_dir_transfer_space(dsl_dir_t *dd, int64_t delta, + dd_used_t oldtype, dd_used_t newtype, dmu_tx_t *tx) +{ + boolean_t needlock = !MUTEX_HELD(&dd->dd_lock); + + ASSERT(dmu_tx_is_syncing(tx)); + ASSERT(oldtype < DD_USED_NUM); + ASSERT(newtype < DD_USED_NUM); + + if (delta == 0 || !(dd->dd_phys->dd_flags & DD_FLAG_USED_BREAKDOWN)) + return; + + dsl_dir_dirty(dd, tx); + if (needlock) + mutex_enter(&dd->dd_lock); + ASSERT(delta > 0 ? + dd->dd_phys->dd_used_breakdown[oldtype] >= delta : + dd->dd_phys->dd_used_breakdown[newtype] >= -delta); + ASSERT(dd->dd_phys->dd_used_bytes >= ABS(delta)); + dd->dd_phys->dd_used_breakdown[oldtype] -= delta; + dd->dd_phys->dd_used_breakdown[newtype] += delta; + if (needlock) + mutex_exit(&dd->dd_lock); +} + static int dsl_dir_set_quota_check(void *arg1, void *arg2, dmu_tx_t *tx) { @@ -968,7 +1020,7 @@ dsl_dir_set_quota_check(void *arg1, void *arg2, dmu_tx_t *tx) towrite = dsl_dir_space_towrite(dd); if ((dmu_tx_is_syncing(tx) || towrite == 0) && (new_quota < dd->dd_phys->dd_reserved || - new_quota < dd->dd_used_bytes + towrite)) { + new_quota < dd->dd_phys->dd_used_bytes + towrite)) { err = ENOSPC; } mutex_exit(&dd->dd_lock); @@ -1038,7 +1090,7 @@ dsl_dir_set_reservation_check(void *arg1, void *arg2, dmu_tx_t *tx) return (0); mutex_enter(&dd->dd_lock); - used = dd->dd_used_bytes; + used = dd->dd_phys->dd_used_bytes; delta = MAX(used, new_reservation) - MAX(used, dd->dd_phys->dd_reserved); mutex_exit(&dd->dd_lock); @@ -1071,16 +1123,17 @@ dsl_dir_set_reservation_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) dmu_buf_will_dirty(dd->dd_dbuf, tx); mutex_enter(&dd->dd_lock); - used = dd->dd_used_bytes; + used = dd->dd_phys->dd_used_bytes; delta = MAX(used, new_reservation) - MAX(used, dd->dd_phys->dd_reserved); dd->dd_phys->dd_reserved = new_reservation; - mutex_exit(&dd->dd_lock); if (dd->dd_parent != NULL) { /* Roll up this additional usage into our ancestors */ - dsl_dir_diduse_space(dd->dd_parent, delta, 0, 0, tx); + dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV, + delta, 0, 0, tx); } + mutex_exit(&dd->dd_lock); spa_history_internal_log(LOG_DS_RESERVATION, dd->dd_pool->dp_spa, tx, cr, "%lld dataset = %llu", @@ -1126,7 +1179,7 @@ would_change(dsl_dir_t *dd, int64_t delta, dsl_dir_t *ancestor) return (delta); mutex_enter(&dd->dd_lock); - delta = parent_delta(dd, dd->dd_used_bytes, delta); + delta = parent_delta(dd, dd->dd_phys->dd_used_bytes, delta); mutex_exit(&dd->dd_lock); return (would_change(dd->dd_parent, delta, ancestor)); } @@ -1162,7 +1215,7 @@ dsl_dir_rename_check(void *arg1, void *arg2, dmu_tx_t *tx) if (ra->newparent != dd->dd_parent) { /* is there enough space? */ uint64_t myspace = - MAX(dd->dd_used_bytes, dd->dd_phys->dd_reserved); + MAX(dd->dd_phys->dd_used_bytes, dd->dd_phys->dd_reserved); /* no rename into our descendant */ if (closest_common_ancestor(dd, ra->newparent) == dd) @@ -1188,15 +1241,24 @@ dsl_dir_rename_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) ASSERT(dmu_buf_refcount(dd->dd_dbuf) <= 2); if (ra->newparent != dd->dd_parent) { - uint64_t myspace = - MAX(dd->dd_used_bytes, dd->dd_phys->dd_reserved); - - dsl_dir_diduse_space(dd->dd_parent, -myspace, + dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD, + -dd->dd_phys->dd_used_bytes, -dd->dd_phys->dd_compressed_bytes, -dd->dd_phys->dd_uncompressed_bytes, tx); - dsl_dir_diduse_space(ra->newparent, myspace, + dsl_dir_diduse_space(ra->newparent, DD_USED_CHILD, + dd->dd_phys->dd_used_bytes, dd->dd_phys->dd_compressed_bytes, dd->dd_phys->dd_uncompressed_bytes, tx); + + if (dd->dd_phys->dd_reserved > dd->dd_phys->dd_used_bytes) { + uint64_t unused_rsrv = dd->dd_phys->dd_reserved - + dd->dd_phys->dd_used_bytes; + + dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV, + -unused_rsrv, 0, 0, tx); + dsl_dir_diduse_space(ra->newparent, DD_USED_CHILD_RSRV, + unused_rsrv, 0, 0, tx); + } } dmu_buf_will_dirty(dd->dd_dbuf, tx); diff --git a/zfs/lib/libzpool/dsl_pool.c b/zfs/lib/libzpool/dsl_pool.c index de8736800..dacc57c81 100644 --- a/zfs/lib/libzpool/dsl_pool.c +++ b/zfs/lib/libzpool/dsl_pool.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dsl_pool.c 1.12 08/03/20 SMI" - #include #include #include @@ -36,23 +34,35 @@ #include #include #include +#include +#include int zfs_no_write_throttle = 0; +int zfs_write_limit_shift = 3; /* 1/8th of physical memory */ +int zfs_txg_synctime = 5; /* target secs to sync a txg */ + +uint64_t zfs_write_limit_min = 32 << 20; /* min write limit is 32MB */ +uint64_t zfs_write_limit_max = 0; /* max data payload per txg */ +uint64_t zfs_write_limit_inflated = 0; uint64_t zfs_write_limit_override = 0; +kmutex_t zfs_write_limit_lock; + +static pgcnt_t old_physmem = 0; + static int -dsl_pool_open_mos_dir(dsl_pool_t *dp, dsl_dir_t **ddp) +dsl_pool_open_special_dir(dsl_pool_t *dp, const char *name, dsl_dir_t **ddp) { uint64_t obj; int err; err = zap_lookup(dp->dp_meta_objset, dp->dp_root_dir->dd_phys->dd_child_dir_zapobj, - MOS_DIR_NAME, sizeof (obj), 1, &obj); + name, sizeof (obj), 1, &obj); if (err) return (err); - return (dsl_dir_open_obj(dp, obj, MOS_DIR_NAME, dp, ddp)); + return (dsl_dir_open_obj(dp, obj, name, dp, ddp)); } static dsl_pool_t * @@ -60,7 +70,6 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg) { dsl_pool_t *dp; blkptr_t *bp = spa_get_rootblkptr(spa); - extern uint64_t zfs_write_limit_min; dp = kmem_zalloc(sizeof (dsl_pool_t), KM_SLEEP); dp->dp_spa = spa; @@ -79,6 +88,7 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg) offsetof(dsl_dataset_t, ds_synced_link)); mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&dp->dp_scrub_cancel_lock, NULL, MUTEX_DEFAULT, NULL); return (dp); } @@ -88,9 +98,11 @@ dsl_pool_open(spa_t *spa, uint64_t txg, dsl_pool_t **dpp) { int err; dsl_pool_t *dp = dsl_pool_open_impl(spa, txg); + dsl_dir_t *dd; + dsl_dataset_t *ds; objset_impl_t *osi; - rw_enter(&dp->dp_config_rwlock, RW_READER); + rw_enter(&dp->dp_config_rwlock, RW_WRITER); err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp, &osi); if (err) goto out; @@ -107,10 +119,73 @@ dsl_pool_open(spa_t *spa, uint64_t txg, dsl_pool_t **dpp) if (err) goto out; - err = dsl_pool_open_mos_dir(dp, &dp->dp_mos_dir); + err = dsl_pool_open_special_dir(dp, MOS_DIR_NAME, &dp->dp_mos_dir); if (err) goto out; + if (spa_version(spa) >= SPA_VERSION_ORIGIN) { + err = dsl_pool_open_special_dir(dp, ORIGIN_DIR_NAME, &dd); + if (err) + goto out; + err = dsl_dataset_hold_obj(dp, dd->dd_phys->dd_head_dataset_obj, + FTAG, &ds); + if (err) + goto out; + err = dsl_dataset_hold_obj(dp, ds->ds_phys->ds_prev_snap_obj, + dp, &dp->dp_origin_snap); + if (err) + goto out; + dsl_dataset_rele(ds, FTAG); + dsl_dir_close(dd, dp); + } + + /* get scrub status */ + err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_FUNC, sizeof (uint32_t), 1, + &dp->dp_scrub_func); + if (err == 0) { + err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_QUEUE, sizeof (uint64_t), 1, + &dp->dp_scrub_queue_obj); + if (err) + goto out; + err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_MIN_TXG, sizeof (uint64_t), 1, + &dp->dp_scrub_min_txg); + if (err) + goto out; + err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_MAX_TXG, sizeof (uint64_t), 1, + &dp->dp_scrub_max_txg); + if (err) + goto out; + err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_BOOKMARK, sizeof (uint64_t), 4, + &dp->dp_scrub_bookmark); + if (err) + goto out; + err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_ERRORS, sizeof (uint64_t), 1, + &spa->spa_scrub_errors); + if (err) + goto out; + if (spa_version(spa) < SPA_VERSION_DSL_SCRUB) { + /* + * A new-type scrub was in progress on an old + * pool. Restart from the beginning, since the + * old software may have changed the pool in the + * meantime. + */ + dsl_pool_scrub_restart(dp); + } + } else { + /* + * It's OK if there is no scrub in progress (and if + * there was an I/O error, ignore it). + */ + err = 0; + } + out: rw_exit(&dp->dp_config_rwlock); if (err) @@ -124,7 +199,15 @@ out: void dsl_pool_close(dsl_pool_t *dp) { - /* drop our reference from dsl_pool_open() */ + /* drop our references from dsl_pool_open() */ + + /* + * Since we held the origin_snap from "syncing" context (which + * includes pool-opening context), it actually only got a "ref" + * and not a hold, so just drop that here. + */ + if (dp->dp_origin_snap) + dsl_dataset_drop_ref(dp->dp_origin_snap, dp); if (dp->dp_mos_dir) dsl_dir_close(dp->dp_mos_dir, dp); if (dp->dp_root_dir) @@ -142,15 +225,23 @@ dsl_pool_close(dsl_pool_t *dp) txg_fini(dp); rw_destroy(&dp->dp_config_rwlock); mutex_destroy(&dp->dp_lock); + mutex_destroy(&dp->dp_scrub_cancel_lock); + if (dp->dp_blkstats) + kmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_t)); kmem_free(dp, sizeof (dsl_pool_t)); } dsl_pool_t * -dsl_pool_create(spa_t *spa, uint64_t txg) +dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg) { int err; dsl_pool_t *dp = dsl_pool_open_impl(spa, txg); dmu_tx_t *tx = dmu_tx_create_assigned(dp, txg); + objset_impl_t *osip; + dsl_dataset_t *ds; + uint64_t dsobj; + + /* create and open the MOS (meta-objset) */ dp->dp_meta_objset = &dmu_objset_create_impl(spa, NULL, &dp->dp_meta_rootbp, DMU_OST_META, tx)->os; @@ -160,13 +251,29 @@ dsl_pool_create(spa_t *spa, uint64_t txg) ASSERT3U(err, ==, 0); /* create and open the root dir */ - dsl_dataset_create_root(dp, &dp->dp_root_dir_obj, tx); + dp->dp_root_dir_obj = dsl_dir_create_sync(dp, NULL, NULL, tx); VERIFY(0 == dsl_dir_open_obj(dp, dp->dp_root_dir_obj, NULL, dp, &dp->dp_root_dir)); /* create and open the meta-objset dir */ - (void) dsl_dir_create_sync(dp->dp_root_dir, MOS_DIR_NAME, tx); - VERIFY(0 == dsl_pool_open_mos_dir(dp, &dp->dp_mos_dir)); + (void) dsl_dir_create_sync(dp, dp->dp_root_dir, MOS_DIR_NAME, tx); + VERIFY(0 == dsl_pool_open_special_dir(dp, + MOS_DIR_NAME, &dp->dp_mos_dir)); + + if (spa_version(spa) >= SPA_VERSION_DSL_SCRUB) + dsl_pool_create_origin(dp, tx); + + /* create the root dataset */ + dsobj = dsl_dataset_create_sync_dd(dp->dp_root_dir, NULL, 0, tx); + + /* create the root objset */ + VERIFY(0 == dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds)); + osip = dmu_objset_create_impl(dp->dp_spa, ds, + dsl_dataset_get_blkptr(ds), DMU_OST_ZFS, tx); +#ifdef _KERNEL + zfs_create_fs(&osip->os, kcred, zplprops, tx); +#endif + dsl_dataset_rele(ds, FTAG); dmu_tx_commit(tx); @@ -182,10 +289,13 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg) dsl_dataset_t *ds; dsl_sync_task_group_t *dstg; objset_impl_t *mosi = dp->dp_meta_objset->os; + hrtime_t start, write_time; + uint64_t data_written; int err; tx = dmu_tx_create_assigned(dp, txg); + dp->dp_read_overhead = 0; zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); while (ds = txg_list_remove(&dp->dp_dirty_datasets, txg)) { if (!list_link_active(&ds->ds_synced_link)) @@ -194,14 +304,27 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg) dmu_buf_rele(ds->ds_dbuf, ds); dsl_dataset_sync(ds, zio, tx); } + DTRACE_PROBE(pool_sync__1setup); + + start = gethrtime(); err = zio_wait(zio); + write_time = gethrtime() - start; ASSERT(err == 0); + DTRACE_PROBE(pool_sync__2rootzio); while (dstg = txg_list_remove(&dp->dp_sync_tasks, txg)) dsl_sync_task_group_sync(dstg, tx); + DTRACE_PROBE(pool_sync__3task); + + start = gethrtime(); while (dd = txg_list_remove(&dp->dp_dirty_dirs, txg)) dsl_dir_sync(dd, tx); + write_time += gethrtime() - start; + if (spa_sync_pass(dp->dp_spa) == 1) + dsl_pool_scrub_sync(dp, tx); + + start = gethrtime(); if (list_head(&mosi->os_dirty_dnodes[txg & TXG_MASK]) != NULL || list_head(&mosi->os_free_dnodes[txg & TXG_MASK]) != NULL) { zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); @@ -211,8 +334,51 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg) dprintf_bp(&dp->dp_meta_rootbp, "meta objset rootbp is %s", ""); spa_set_rootblkptr(dp->dp_spa, &dp->dp_meta_rootbp); } + write_time += gethrtime() - start; + DTRACE_PROBE2(pool_sync__4io, hrtime_t, write_time, + hrtime_t, dp->dp_read_overhead); + write_time -= dp->dp_read_overhead; dmu_tx_commit(tx); + + data_written = dp->dp_space_towrite[txg & TXG_MASK]; + dp->dp_space_towrite[txg & TXG_MASK] = 0; + ASSERT(dp->dp_tempreserved[txg & TXG_MASK] == 0); + + /* + * If the write limit max has not been explicitly set, set it + * to a fraction of available physical memory (default 1/8th). + * Note that we must inflate the limit because the spa + * inflates write sizes to account for data replication. + * Check this each sync phase to catch changing memory size. + */ + if (physmem != old_physmem && zfs_write_limit_shift) { + mutex_enter(&zfs_write_limit_lock); + old_physmem = physmem; + zfs_write_limit_max = ptob(physmem) >> zfs_write_limit_shift; + zfs_write_limit_inflated = MAX(zfs_write_limit_min, + spa_get_asize(dp->dp_spa, zfs_write_limit_max)); + mutex_exit(&zfs_write_limit_lock); + } + + /* + * Attempt to keep the sync time consistent by adjusting the + * amount of write traffic allowed into each transaction group. + * Weight the throughput calculation towards the current value: + * thru = 3/4 old_thru + 1/4 new_thru + */ + ASSERT(zfs_write_limit_min > 0); + if (data_written > zfs_write_limit_min / 8 && write_time > 0) { + uint64_t throughput = (data_written * NANOSEC) / write_time; + if (dp->dp_throughput) + dp->dp_throughput = throughput / 4 + + 3 * dp->dp_throughput / 4; + else + dp->dp_throughput = throughput; + dp->dp_write_limit = MIN(zfs_write_limit_inflated, + MAX(zfs_write_limit_min, + dp->dp_throughput * zfs_txg_synctime)); + } } void @@ -270,7 +436,8 @@ dsl_pool_tempreserve_space(dsl_pool_t *dp, uint64_t space, dmu_tx_t *tx) zfs_write_limit_override : dp->dp_write_limit); if (zfs_no_write_throttle) { - dp->dp_tempreserved[tx->tx_txg & TXG_MASK] += space; + atomic_add_64(&dp->dp_tempreserved[tx->tx_txg & TXG_MASK], + space); return (0); } @@ -297,7 +464,7 @@ dsl_pool_tempreserve_space(dsl_pool_t *dp, uint64_t space, dmu_tx_t *tx) * the caller 1 clock tick. This will slow down the "fill" * rate until the sync process can catch up with us. */ - if (reserved && reserved > (write_limit - write_limit << 3)) + if (reserved && reserved > (write_limit - (write_limit >> 3))) txg_delay(dp, tx->tx_txg, 1); return (0); @@ -313,7 +480,6 @@ dsl_pool_tempreserve_clear(dsl_pool_t *dp, int64_t space, dmu_tx_t *tx) void dsl_pool_memory_pressure(dsl_pool_t *dp) { - extern uint64_t zfs_write_limit_min; uint64_t space_inuse = 0; int i; @@ -337,3 +503,111 @@ dsl_pool_willuse_space(dsl_pool_t *dp, int64_t space, dmu_tx_t *tx) mutex_exit(&dp->dp_lock); } } + +/* ARGSUSED */ +static int +upgrade_clones_cb(spa_t *spa, uint64_t dsobj, const char *dsname, void *arg) +{ + dmu_tx_t *tx = arg; + dsl_dataset_t *ds, *prev = NULL; + int err; + dsl_pool_t *dp = spa_get_dsl(spa); + + err = dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds); + if (err) + return (err); + + while (ds->ds_phys->ds_prev_snap_obj != 0) { + err = dsl_dataset_hold_obj(dp, ds->ds_phys->ds_prev_snap_obj, + FTAG, &prev); + if (err) { + dsl_dataset_rele(ds, FTAG); + return (err); + } + + if (prev->ds_phys->ds_next_snap_obj != ds->ds_object) + break; + dsl_dataset_rele(ds, FTAG); + ds = prev; + prev = NULL; + } + + if (prev == NULL) { + prev = dp->dp_origin_snap; + + /* + * The $ORIGIN can't have any data, or the accounting + * will be wrong. + */ + ASSERT(prev->ds_phys->ds_bp.blk_birth == 0); + + /* The origin doesn't get attached to itself */ + if (ds->ds_object == prev->ds_object) { + dsl_dataset_rele(ds, FTAG); + return (0); + } + + dmu_buf_will_dirty(ds->ds_dbuf, tx); + ds->ds_phys->ds_prev_snap_obj = prev->ds_object; + ds->ds_phys->ds_prev_snap_txg = prev->ds_phys->ds_creation_txg; + + dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx); + ds->ds_dir->dd_phys->dd_origin_obj = prev->ds_object; + + dmu_buf_will_dirty(prev->ds_dbuf, tx); + prev->ds_phys->ds_num_children++; + + if (ds->ds_phys->ds_next_snap_obj == 0) { + ASSERT(ds->ds_prev == NULL); + VERIFY(0 == dsl_dataset_hold_obj(dp, + ds->ds_phys->ds_prev_snap_obj, ds, &ds->ds_prev)); + } + } + + ASSERT(ds->ds_dir->dd_phys->dd_origin_obj == prev->ds_object); + ASSERT(ds->ds_phys->ds_prev_snap_obj == prev->ds_object); + + if (prev->ds_phys->ds_next_clones_obj == 0) { + prev->ds_phys->ds_next_clones_obj = + zap_create(dp->dp_meta_objset, + DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx); + } + VERIFY(0 == zap_add_int(dp->dp_meta_objset, + prev->ds_phys->ds_next_clones_obj, ds->ds_object, tx)); + + dsl_dataset_rele(ds, FTAG); + if (prev != dp->dp_origin_snap) + dsl_dataset_rele(prev, FTAG); + return (0); +} + +void +dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx) +{ + ASSERT(dmu_tx_is_syncing(tx)); + ASSERT(dp->dp_origin_snap != NULL); + + (void) dmu_objset_find_spa(dp->dp_spa, NULL, upgrade_clones_cb, + tx, DS_FIND_CHILDREN); +} + +void +dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx) +{ + uint64_t dsobj; + dsl_dataset_t *ds; + + ASSERT(dmu_tx_is_syncing(tx)); + ASSERT(dp->dp_origin_snap == NULL); + + /* create the origin dir, ds, & snap-ds */ + rw_enter(&dp->dp_config_rwlock, RW_WRITER); + dsobj = dsl_dataset_create_sync(dp->dp_root_dir, ORIGIN_DIR_NAME, + NULL, 0, kcred, tx); + VERIFY(0 == dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds)); + dsl_dataset_snapshot_sync(ds, ORIGIN_DIR_NAME, kcred, tx); + VERIFY(0 == dsl_dataset_hold_obj(dp, ds->ds_phys->ds_prev_snap_obj, + dp, &dp->dp_origin_snap)); + dsl_dataset_rele(ds, FTAG); + rw_exit(&dp->dp_config_rwlock); +} diff --git a/zfs/lib/libzpool/dsl_prop.c b/zfs/lib/libzpool/dsl_prop.c index 364a713fe..212acbbc5 100644 --- a/zfs/lib/libzpool/dsl_prop.c +++ b/zfs/lib/libzpool/dsl_prop.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dsl_prop.c 1.16 08/02/20 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -68,13 +68,16 @@ dodefault(const char *propname, int intsz, int numint, void *buf) return (0); } -static int -dsl_prop_get_impl(dsl_dir_t *dd, const char *propname, +int +dsl_prop_get_dd(dsl_dir_t *dd, const char *propname, int intsz, int numint, void *buf, char *setpoint) { int err = ENOENT; + objset_t *mos = dd->dd_pool->dp_meta_objset; zfs_prop_t prop; + ASSERT(RW_LOCK_HELD(&dd->dd_pool->dp_config_rwlock)); + if (setpoint) setpoint[0] = '\0'; @@ -85,7 +88,6 @@ dsl_prop_get_impl(dsl_dir_t *dd, const char *propname, * ouside this loop. */ for (; dd != NULL; dd = dd->dd_parent) { - objset_t *mos = dd->dd_pool->dp_meta_objset; ASSERT(RW_LOCK_HELD(&dd->dd_pool->dp_config_rwlock)); err = zap_lookup(mos, dd->dd_phys->dd_props_zapobj, propname, intsz, numint, buf); @@ -107,6 +109,26 @@ dsl_prop_get_impl(dsl_dir_t *dd, const char *propname, return (err); } +int +dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname, + int intsz, int numint, void *buf, char *setpoint) +{ + ASSERT(RW_LOCK_HELD(&ds->ds_dir->dd_pool->dp_config_rwlock)); + + if (ds->ds_phys->ds_props_obj) { + int err = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset, + ds->ds_phys->ds_props_obj, propname, intsz, numint, buf); + if (err != ENOENT) { + if (setpoint) + dsl_dataset_name(ds, setpoint); + return (err); + } + } + + return (dsl_prop_get_dd(ds->ds_dir, propname, + intsz, numint, buf, setpoint)); +} + /* * Register interest in the named property. We'll call the callback * once to notify it of the current property value, and again each time @@ -119,19 +141,20 @@ dsl_prop_register(dsl_dataset_t *ds, const char *propname, dsl_prop_changed_cb_t *callback, void *cbarg) { dsl_dir_t *dd = ds->ds_dir; + dsl_pool_t *dp = dd->dd_pool; uint64_t value; dsl_prop_cb_record_t *cbr; int err; int need_rwlock; - need_rwlock = !RW_WRITE_HELD(&dd->dd_pool->dp_config_rwlock); + need_rwlock = !RW_WRITE_HELD(&dp->dp_config_rwlock); if (need_rwlock) - rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); + rw_enter(&dp->dp_config_rwlock, RW_READER); - err = dsl_prop_get_impl(dd, propname, 8, 1, &value, NULL); + err = dsl_prop_get_ds(ds, propname, 8, 1, &value, NULL); if (err != 0) { if (need_rwlock) - rw_exit(&dd->dd_pool->dp_config_rwlock); + rw_exit(&dp->dp_config_rwlock); return (err); } @@ -147,56 +170,30 @@ dsl_prop_register(dsl_dataset_t *ds, const char *propname, cbr->cbr_func(cbr->cbr_arg, value); - VERIFY(0 == dsl_dir_open_obj(dd->dd_pool, dd->dd_object, + VERIFY(0 == dsl_dir_open_obj(dp, dd->dd_object, NULL, cbr, &dd)); if (need_rwlock) - rw_exit(&dd->dd_pool->dp_config_rwlock); - /* Leave dataset open until this callback is unregistered */ + rw_exit(&dp->dp_config_rwlock); + /* Leave dir open until this callback is unregistered */ return (0); } int -dsl_prop_get_ds(dsl_dir_t *dd, const char *propname, +dsl_prop_get(const char *dsname, const char *propname, int intsz, int numints, void *buf, char *setpoint) { + dsl_dataset_t *ds; int err; - rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); - err = dsl_prop_get_impl(dd, propname, intsz, numints, buf, setpoint); - rw_exit(&dd->dd_pool->dp_config_rwlock); - - return (err); -} - -/* - * Get property when config lock is already held. - */ -int dsl_prop_get_ds_locked(dsl_dir_t *dd, const char *propname, - int intsz, int numints, void *buf, char *setpoint) -{ - ASSERT(RW_LOCK_HELD(&dd->dd_pool->dp_config_rwlock)); - return (dsl_prop_get_impl(dd, propname, intsz, numints, buf, setpoint)); -} - -int -dsl_prop_get(const char *ddname, const char *propname, - int intsz, int numints, void *buf, char *setpoint) -{ - dsl_dir_t *dd; - const char *tail; - int err; - - err = dsl_dir_open(ddname, FTAG, &dd, &tail); + err = dsl_dataset_hold(dsname, FTAG, &ds); if (err) return (err); - if (tail && tail[0] != '@') { - dsl_dir_close(dd, FTAG); - return (ENOENT); - } - err = dsl_prop_get_ds(dd, propname, intsz, numints, buf, setpoint); + rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER); + err = dsl_prop_get_ds(ds, propname, intsz, numints, buf, setpoint); + rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock); - dsl_dir_close(dd, FTAG); + dsl_dataset_rele(ds, FTAG); return (err); } @@ -282,6 +279,7 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj, zap_cursor_t zc; zap_attribute_t *za; int err; + uint64_t dummyval; ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock)); err = dsl_dir_open_obj(dp, ddobj, NULL, FTAG, &dd); @@ -294,7 +292,7 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj, * being inherited here or below; stop the recursion. */ err = zap_lookup(mos, dd->dd_phys->dd_props_zapobj, propname, - 8, 1, &value); + 8, 1, &dummyval); if (err == 0) { dsl_dir_close(dd, FTAG); return; @@ -303,11 +301,22 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj, } mutex_enter(&dd->dd_lock); - for (cbr = list_head(&dd->dd_prop_cbs); - cbr; cbr = list_next(&dd->dd_prop_cbs, cbr)) { - if (strcmp(cbr->cbr_propname, propname) == 0) { - cbr->cbr_func(cbr->cbr_arg, value); - } + for (cbr = list_head(&dd->dd_prop_cbs); cbr; + cbr = list_next(&dd->dd_prop_cbs, cbr)) { + uint64_t propobj = cbr->cbr_ds->ds_phys->ds_props_obj; + + if (strcmp(cbr->cbr_propname, propname) != 0) + continue; + + /* + * If the property is set on this ds, then it is not + * inherited here; don't call the callback. + */ + if (propobj && 0 == zap_lookup(mos, propobj, propname, + 8, 1, &dummyval)) + continue; + + cbr->cbr_func(cbr->cbr_arg, value); } mutex_exit(&dd->dd_lock); @@ -335,22 +344,35 @@ struct prop_set_arg { static void dsl_prop_set_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) { - dsl_dir_t *dd = arg1; + dsl_dataset_t *ds = arg1; struct prop_set_arg *psa = arg2; - objset_t *mos = dd->dd_pool->dp_meta_objset; - uint64_t zapobj = dd->dd_phys->dd_props_zapobj; - uint64_t intval; + objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; + uint64_t zapobj, intval; int isint; char valbuf[32]; char *valstr; isint = (dodefault(psa->name, 8, 1, &intval) == 0); + if (dsl_dataset_is_snapshot(ds)) { + ASSERT(spa_version(ds->ds_dir->dd_pool->dp_spa) >= + SPA_VERSION_SNAP_PROPS); + if (ds->ds_phys->ds_props_obj == 0) { + dmu_buf_will_dirty(ds->ds_dbuf, tx); + ds->ds_phys->ds_props_obj = + zap_create(mos, + DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx); + } + zapobj = ds->ds_phys->ds_props_obj; + } else { + zapobj = ds->ds_dir->dd_phys->dd_props_zapobj; + } + if (psa->numints == 0) { int err = zap_remove(mos, zapobj, psa->name, tx); ASSERT(err == 0 || err == ENOENT); if (isint) { - VERIFY(0 == dsl_prop_get_impl(dd->dd_parent, + VERIFY(0 == dsl_prop_get_ds(ds, psa->name, 8, 1, &intval, NULL)); } } else { @@ -361,8 +383,25 @@ dsl_prop_set_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) } if (isint) { - dsl_prop_changed_notify(dd->dd_pool, - dd->dd_object, psa->name, intval, TRUE); + if (dsl_dataset_is_snapshot(ds)) { + dsl_prop_cb_record_t *cbr; + /* + * It's a snapshot; nothing can inherit this + * property, so just look for callbacks on this + * ds here. + */ + mutex_enter(&ds->ds_dir->dd_lock); + for (cbr = list_head(&ds->ds_dir->dd_prop_cbs); cbr; + cbr = list_next(&ds->ds_dir->dd_prop_cbs, cbr)) { + if (cbr->cbr_ds == ds && + strcmp(cbr->cbr_propname, psa->name) == 0) + cbr->cbr_func(cbr->cbr_arg, intval); + } + mutex_exit(&ds->ds_dir->dd_lock); + } else { + dsl_prop_changed_notify(ds->ds_dir->dd_pool, + ds->ds_dir->dd_object, psa->name, intval, TRUE); + } } if (isint) { (void) snprintf(valbuf, sizeof (valbuf), @@ -372,9 +411,8 @@ dsl_prop_set_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) valstr = (char *)psa->buf; } spa_history_internal_log((psa->numints == 0) ? LOG_DS_INHERIT : - LOG_DS_PROPSET, dd->dd_pool->dp_spa, tx, cr, - "%s=%s dataset = %llu", psa->name, valstr, - dd->dd_phys->dd_head_dataset_obj); + LOG_DS_PROPSET, ds->ds_dir->dd_pool->dp_spa, tx, cr, + "%s=%s dataset = %llu", psa->name, valstr, ds->ds_object); } void @@ -396,26 +434,12 @@ dsl_prop_set_uint64_sync(dsl_dir_t *dd, const char *name, uint64_t val, } int -dsl_prop_set_dd(dsl_dir_t *dd, const char *propname, +dsl_prop_set(const char *dsname, const char *propname, int intsz, int numints, const void *buf) { - struct prop_set_arg psa; - - psa.name = propname; - psa.intsz = intsz; - psa.numints = numints; - psa.buf = buf; - - return (dsl_sync_task_do(dd->dd_pool, - NULL, dsl_prop_set_sync, dd, &psa, 2)); -} - -int -dsl_prop_set(const char *ddname, const char *propname, - int intsz, int numints, const void *buf) -{ - dsl_dir_t *dd; + dsl_dataset_t *ds; int err; + struct prop_set_arg psa; /* * We must do these checks before we get to the syncfunc, since @@ -426,11 +450,24 @@ dsl_prop_set(const char *ddname, const char *propname, if (intsz * numints >= ZAP_MAXVALUELEN) return (E2BIG); - err = dsl_dir_open(ddname, FTAG, &dd, NULL); + err = dsl_dataset_hold(dsname, FTAG, &ds); if (err) return (err); - err = dsl_prop_set_dd(dd, propname, intsz, numints, buf); - dsl_dir_close(dd, FTAG); + + if (dsl_dataset_is_snapshot(ds) && + spa_version(ds->ds_dir->dd_pool->dp_spa) < SPA_VERSION_SNAP_PROPS) { + dsl_dataset_rele(ds, FTAG); + return (ENOTSUP); + } + + psa.name = propname; + psa.intsz = intsz; + psa.numints = numints; + psa.buf = buf; + err = dsl_sync_task_do(ds->ds_dir->dd_pool, + NULL, dsl_prop_set_sync, ds, &psa, 2); + + dsl_dataset_rele(ds, FTAG); return (err); } @@ -438,47 +475,55 @@ dsl_prop_set(const char *ddname, const char *propname, * Iterate over all properties for this dataset and return them in an nvlist. */ int -dsl_prop_get_all(objset_t *os, nvlist_t **nvp) +dsl_prop_get_all(objset_t *os, nvlist_t **nvp, boolean_t local) { dsl_dataset_t *ds = os->os->os_dsl_dataset; dsl_dir_t *dd = ds->ds_dir; - boolean_t snapshot; + boolean_t snapshot = dsl_dataset_is_snapshot(ds); int err = 0; - dsl_pool_t *dp; - objset_t *mos; - - snapshot = dsl_dataset_is_snapshot(ds); + dsl_pool_t *dp = dd->dd_pool; + objset_t *mos = dp->dp_meta_objset; + uint64_t propobj = ds->ds_phys->ds_props_obj; VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0); - dp = dd->dd_pool; - mos = dp->dp_meta_objset; + if (local && snapshot && !propobj) + return (0); rw_enter(&dp->dp_config_rwlock, RW_READER); - for (; dd != NULL; dd = dd->dd_parent) { + while (dd != NULL) { char setpoint[MAXNAMELEN]; zap_cursor_t zc; zap_attribute_t za; + dsl_dir_t *dd_next; - dsl_dir_name(dd, setpoint); + if (propobj) { + dsl_dataset_name(ds, setpoint); + dd_next = dd; + } else { + dsl_dir_name(dd, setpoint); + propobj = dd->dd_phys->dd_props_zapobj; + dd_next = dd->dd_parent; + } - for (zap_cursor_init(&zc, mos, dd->dd_phys->dd_props_zapobj); + for (zap_cursor_init(&zc, mos, propobj); (err = zap_cursor_retrieve(&zc, &za)) == 0; zap_cursor_advance(&zc)) { nvlist_t *propval; - zfs_prop_t prop; - /* - * Skip non-inheritable properties. - */ - if ((prop = zfs_name_to_prop(za.za_name)) != - ZPROP_INVAL && !zfs_prop_inheritable(prop) && - dd != ds->ds_dir) + zfs_prop_t prop = zfs_name_to_prop(za.za_name); + + /* Skip non-inheritable properties. */ + if (prop != ZPROP_INVAL && + !zfs_prop_inheritable(prop) && + (dd != ds->ds_dir || (snapshot && dd != dd_next))) continue; - if (snapshot && + /* Skip properties not valid for this type. */ + if (snapshot && prop != ZPROP_INVAL && !zfs_prop_valid_for_type(prop, ZFS_TYPE_SNAPSHOT)) continue; + /* Skip properties already defined */ if (nvlist_lookup_nvlist(*nvp, za.za_name, &propval) == 0) continue; @@ -491,10 +536,8 @@ dsl_prop_get_all(objset_t *os, nvlist_t **nvp) */ char *tmp = kmem_alloc(za.za_num_integers, KM_SLEEP); - err = zap_lookup(mos, - dd->dd_phys->dd_props_zapobj, - za.za_name, 1, za.za_num_integers, - tmp); + err = zap_lookup(mos, propobj, + za.za_name, 1, za.za_num_integers, tmp); if (err != 0) { kmem_free(tmp, za.za_num_integers); break; @@ -522,6 +565,14 @@ dsl_prop_get_all(objset_t *os, nvlist_t **nvp) if (err != ENOENT) break; err = 0; + /* + * If we are just after the props that have been set + * locally, then we are done after the first iteration. + */ + if (local) + break; + dd = dd_next; + propobj = 0; } rw_exit(&dp->dp_config_rwlock); diff --git a/zfs/lib/libzpool/dsl_scrub.c b/zfs/lib/libzpool/dsl_scrub.c new file mode 100644 index 000000000..950a91f78 --- /dev/null +++ b/zfs/lib/libzpool/dsl_scrub.c @@ -0,0 +1,1014 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int (scrub_cb_t)(dsl_pool_t *, const blkptr_t *, const zbookmark_t *); + +static scrub_cb_t dsl_pool_scrub_clean_cb; +static dsl_syncfunc_t dsl_pool_scrub_cancel_sync; + +int zfs_scrub_min_time = 1; /* scrub for at least 1 sec each txg */ +int zfs_resilver_min_time = 3; /* resilver for at least 3 sec each txg */ +boolean_t zfs_no_scrub_io = B_FALSE; /* set to disable scrub i/o */ + +extern int zfs_txg_timeout; + +static scrub_cb_t *scrub_funcs[SCRUB_FUNC_NUMFUNCS] = { + NULL, + dsl_pool_scrub_clean_cb +}; + +#define SET_BOOKMARK(zb, objset, object, level, blkid) \ +{ \ + (zb)->zb_objset = objset; \ + (zb)->zb_object = object; \ + (zb)->zb_level = level; \ + (zb)->zb_blkid = blkid; \ +} + +/* ARGSUSED */ +static void +dsl_pool_scrub_setup_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) +{ + dsl_pool_t *dp = arg1; + enum scrub_func *funcp = arg2; + dmu_object_type_t ot = 0; + boolean_t complete = B_FALSE; + + dsl_pool_scrub_cancel_sync(dp, &complete, cr, tx); + + ASSERT(dp->dp_scrub_func == SCRUB_FUNC_NONE); + ASSERT(*funcp > SCRUB_FUNC_NONE); + ASSERT(*funcp < SCRUB_FUNC_NUMFUNCS); + + dp->dp_scrub_min_txg = 0; + dp->dp_scrub_max_txg = tx->tx_txg; + + if (*funcp == SCRUB_FUNC_CLEAN) { + vdev_t *rvd = dp->dp_spa->spa_root_vdev; + + /* rewrite all disk labels */ + vdev_config_dirty(rvd); + + if (vdev_resilver_needed(rvd, + &dp->dp_scrub_min_txg, &dp->dp_scrub_max_txg)) { + spa_event_notify(dp->dp_spa, NULL, + ESC_ZFS_RESILVER_START); + dp->dp_scrub_max_txg = MIN(dp->dp_scrub_max_txg, + tx->tx_txg); + } + + /* zero out the scrub stats in all vdev_stat_t's */ + vdev_scrub_stat_update(rvd, + dp->dp_scrub_min_txg ? POOL_SCRUB_RESILVER : + POOL_SCRUB_EVERYTHING, B_FALSE); + + dp->dp_spa->spa_scrub_started = B_TRUE; + } + + /* back to the generic stuff */ + + if (dp->dp_blkstats == NULL) { + dp->dp_blkstats = + kmem_alloc(sizeof (zfs_all_blkstats_t), KM_SLEEP); + } + bzero(dp->dp_blkstats, sizeof (zfs_all_blkstats_t)); + + if (spa_version(dp->dp_spa) < SPA_VERSION_DSL_SCRUB) + ot = DMU_OT_ZAP_OTHER; + + dp->dp_scrub_func = *funcp; + dp->dp_scrub_queue_obj = zap_create(dp->dp_meta_objset, + ot ? ot : DMU_OT_SCRUB_QUEUE, DMU_OT_NONE, 0, tx); + bzero(&dp->dp_scrub_bookmark, sizeof (zbookmark_t)); + dp->dp_scrub_restart = B_FALSE; + dp->dp_spa->spa_scrub_errors = 0; + + VERIFY(0 == zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_FUNC, sizeof (uint32_t), 1, + &dp->dp_scrub_func, tx)); + VERIFY(0 == zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_QUEUE, sizeof (uint64_t), 1, + &dp->dp_scrub_queue_obj, tx)); + VERIFY(0 == zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_MIN_TXG, sizeof (uint64_t), 1, + &dp->dp_scrub_min_txg, tx)); + VERIFY(0 == zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_MAX_TXG, sizeof (uint64_t), 1, + &dp->dp_scrub_max_txg, tx)); + VERIFY(0 == zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_BOOKMARK, sizeof (uint64_t), 4, + &dp->dp_scrub_bookmark, tx)); + VERIFY(0 == zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_ERRORS, sizeof (uint64_t), 1, + &dp->dp_spa->spa_scrub_errors, tx)); + + spa_history_internal_log(LOG_POOL_SCRUB, dp->dp_spa, tx, cr, + "func=%u mintxg=%llu maxtxg=%llu", + *funcp, dp->dp_scrub_min_txg, dp->dp_scrub_max_txg); +} + +int +dsl_pool_scrub_setup(dsl_pool_t *dp, enum scrub_func func) +{ + return (dsl_sync_task_do(dp, NULL, + dsl_pool_scrub_setup_sync, dp, &func, 0)); +} + +/* ARGSUSED */ +static void +dsl_pool_scrub_cancel_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) +{ + dsl_pool_t *dp = arg1; + boolean_t *completep = arg2; + + if (dp->dp_scrub_func == SCRUB_FUNC_NONE) + return; + + mutex_enter(&dp->dp_scrub_cancel_lock); + + if (dp->dp_scrub_restart) { + dp->dp_scrub_restart = B_FALSE; + *completep = B_FALSE; + } + + /* XXX this is scrub-clean specific */ + mutex_enter(&dp->dp_spa->spa_scrub_lock); + while (dp->dp_spa->spa_scrub_inflight > 0) { + cv_wait(&dp->dp_spa->spa_scrub_io_cv, + &dp->dp_spa->spa_scrub_lock); + } + mutex_exit(&dp->dp_spa->spa_scrub_lock); + dp->dp_spa->spa_scrub_started = B_FALSE; + dp->dp_spa->spa_scrub_active = B_FALSE; + + dp->dp_scrub_func = SCRUB_FUNC_NONE; + VERIFY(0 == dmu_object_free(dp->dp_meta_objset, + dp->dp_scrub_queue_obj, tx)); + dp->dp_scrub_queue_obj = 0; + bzero(&dp->dp_scrub_bookmark, sizeof (zbookmark_t)); + + VERIFY(0 == zap_remove(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_QUEUE, tx)); + VERIFY(0 == zap_remove(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_MIN_TXG, tx)); + VERIFY(0 == zap_remove(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_MAX_TXG, tx)); + VERIFY(0 == zap_remove(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_BOOKMARK, tx)); + VERIFY(0 == zap_remove(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_FUNC, tx)); + VERIFY(0 == zap_remove(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_ERRORS, tx)); + + spa_history_internal_log(LOG_POOL_SCRUB_DONE, dp->dp_spa, tx, cr, + "complete=%u", *completep); + + /* below is scrub-clean specific */ + vdev_scrub_stat_update(dp->dp_spa->spa_root_vdev, POOL_SCRUB_NONE, + *completep); + /* + * If the scrub/resilver completed, update all DTLs to reflect this. + * Whether it succeeded or not, vacate all temporary scrub DTLs. + */ + vdev_dtl_reassess(dp->dp_spa->spa_root_vdev, tx->tx_txg, + *completep ? dp->dp_scrub_max_txg : 0, B_TRUE); + if (dp->dp_scrub_min_txg && *completep) + spa_event_notify(dp->dp_spa, NULL, ESC_ZFS_RESILVER_FINISH); + spa_errlog_rotate(dp->dp_spa); + + /* + * We may have finished replacing a device. + * Let the async thread assess this and handle the detach. + */ + spa_async_request(dp->dp_spa, SPA_ASYNC_RESILVER_DONE); + + dp->dp_scrub_min_txg = dp->dp_scrub_max_txg = 0; + mutex_exit(&dp->dp_scrub_cancel_lock); +} + +int +dsl_pool_scrub_cancel(dsl_pool_t *dp) +{ + boolean_t complete = B_FALSE; + + return (dsl_sync_task_do(dp, NULL, + dsl_pool_scrub_cancel_sync, dp, &complete, 3)); +} + +int +dsl_free(zio_t *pio, dsl_pool_t *dp, uint64_t txg, const blkptr_t *bpp, + zio_done_func_t *done, void *private, uint32_t arc_flags) +{ + /* + * This function will be used by bp-rewrite wad to intercept frees. + */ + return (arc_free(pio, dp->dp_spa, txg, (blkptr_t *)bpp, + done, private, arc_flags)); +} + +static boolean_t +bookmark_is_zero(const zbookmark_t *zb) +{ + return (zb->zb_objset == 0 && zb->zb_object == 0 && + zb->zb_level == 0 && zb->zb_blkid == 0); +} + +/* dnp is the dnode for zb1->zb_object */ +static boolean_t +bookmark_is_before(dnode_phys_t *dnp, const zbookmark_t *zb1, + const zbookmark_t *zb2) +{ + uint64_t zb1nextL0, zb2thisobj; + + ASSERT(zb1->zb_objset == zb2->zb_objset); + ASSERT(zb1->zb_object != -1ULL); + ASSERT(zb2->zb_level == 0); + + /* + * A bookmark in the deadlist is considered to be after + * everything else. + */ + if (zb2->zb_object == -1ULL) + return (B_TRUE); + + /* The objset_phys_t isn't before anything. */ + if (dnp == NULL) + return (B_FALSE); + + zb1nextL0 = (zb1->zb_blkid + 1) << + ((zb1->zb_level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT)); + + zb2thisobj = zb2->zb_object ? zb2->zb_object : + zb2->zb_blkid << (DNODE_BLOCK_SHIFT - DNODE_SHIFT); + + if (zb1->zb_object == 0) { + uint64_t nextobj = zb1nextL0 * + (dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT) >> DNODE_SHIFT; + return (nextobj <= zb2thisobj); + } + + if (zb1->zb_object < zb2thisobj) + return (B_TRUE); + if (zb1->zb_object > zb2thisobj) + return (B_FALSE); + if (zb2->zb_object == 0) + return (B_FALSE); + return (zb1nextL0 <= zb2->zb_blkid); +} + +static boolean_t +scrub_pause(dsl_pool_t *dp, const zbookmark_t *zb) +{ + int elapsed_ticks; + int mintime; + + if (dp->dp_scrub_pausing) + return (B_TRUE); /* we're already pausing */ + + if (!bookmark_is_zero(&dp->dp_scrub_bookmark)) + return (B_FALSE); /* we're resuming */ + + /* We only know how to resume from level-0 blocks. */ + if (zb->zb_level != 0) + return (B_FALSE); + + mintime = dp->dp_scrub_isresilver ? zfs_resilver_min_time : + zfs_scrub_min_time; + elapsed_ticks = lbolt64 - dp->dp_scrub_start_time; + if (elapsed_ticks > hz * zfs_txg_timeout || + (elapsed_ticks > hz * mintime && txg_sync_waiting(dp))) { + dprintf("pausing at %llx/%llx/%llx/%llx\n", + (longlong_t)zb->zb_objset, (longlong_t)zb->zb_object, + (longlong_t)zb->zb_level, (longlong_t)zb->zb_blkid); + dp->dp_scrub_pausing = B_TRUE; + dp->dp_scrub_bookmark = *zb; + return (B_TRUE); + } + return (B_FALSE); +} + +typedef struct zil_traverse_arg { + dsl_pool_t *zta_dp; + zil_header_t *zta_zh; +} zil_traverse_arg_t; + +/* ARGSUSED */ +static void +traverse_zil_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg) +{ + zil_traverse_arg_t *zta = arg; + dsl_pool_t *dp = zta->zta_dp; + zil_header_t *zh = zta->zta_zh; + zbookmark_t zb; + + if (bp->blk_birth <= dp->dp_scrub_min_txg) + return; + + if (claim_txg == 0 && bp->blk_birth >= spa_first_txg(dp->dp_spa)) + return; + + zb.zb_objset = zh->zh_log.blk_cksum.zc_word[ZIL_ZC_OBJSET]; + zb.zb_object = 0; + zb.zb_level = -1; + zb.zb_blkid = bp->blk_cksum.zc_word[ZIL_ZC_SEQ]; + VERIFY(0 == scrub_funcs[dp->dp_scrub_func](dp, bp, &zb)); +} + +/* ARGSUSED */ +static void +traverse_zil_record(zilog_t *zilog, lr_t *lrc, void *arg, uint64_t claim_txg) +{ + if (lrc->lrc_txtype == TX_WRITE) { + zil_traverse_arg_t *zta = arg; + dsl_pool_t *dp = zta->zta_dp; + zil_header_t *zh = zta->zta_zh; + lr_write_t *lr = (lr_write_t *)lrc; + blkptr_t *bp = &lr->lr_blkptr; + zbookmark_t zb; + + if (bp->blk_birth <= dp->dp_scrub_min_txg) + return; + + if (claim_txg == 0 || bp->blk_birth < claim_txg) + return; + + zb.zb_objset = zh->zh_log.blk_cksum.zc_word[ZIL_ZC_OBJSET]; + zb.zb_object = lr->lr_foid; + zb.zb_level = BP_GET_LEVEL(bp); + zb.zb_blkid = lr->lr_offset / BP_GET_LSIZE(bp); + VERIFY(0 == scrub_funcs[dp->dp_scrub_func](dp, bp, &zb)); + } +} + +static void +traverse_zil(dsl_pool_t *dp, zil_header_t *zh) +{ + uint64_t claim_txg = zh->zh_claim_txg; + zil_traverse_arg_t zta = { dp, zh }; + zilog_t *zilog; + + /* + * We only want to visit blocks that have been claimed but not yet + * replayed (or, in read-only mode, blocks that *would* be claimed). + */ + if (claim_txg == 0 && (spa_mode & FWRITE)) + return; + + zilog = zil_alloc(dp->dp_meta_objset, zh); + + (void) zil_parse(zilog, traverse_zil_block, traverse_zil_record, &zta, + claim_txg); + + zil_free(zilog); +} + +static void +scrub_visitbp(dsl_pool_t *dp, dnode_phys_t *dnp, + arc_buf_t *pbuf, blkptr_t *bp, const zbookmark_t *zb) +{ + int err; + arc_buf_t *buf = NULL; + + if (bp->blk_birth == 0) + return; + + if (bp->blk_birth <= dp->dp_scrub_min_txg) + return; + + if (scrub_pause(dp, zb)) + return; + + if (!bookmark_is_zero(&dp->dp_scrub_bookmark)) { + /* + * If we already visited this bp & everything below (in + * a prior txg), don't bother doing it again. + */ + if (bookmark_is_before(dnp, zb, &dp->dp_scrub_bookmark)) + return; + + /* + * If we found the block we're trying to resume from, or + * we went past it to a different object, zero it out to + * indicate that it's OK to start checking for pausing + * again. + */ + if (bcmp(zb, &dp->dp_scrub_bookmark, sizeof (*zb)) == 0 || + zb->zb_object > dp->dp_scrub_bookmark.zb_object) { + dprintf("resuming at %llx/%llx/%llx/%llx\n", + (longlong_t)zb->zb_objset, + (longlong_t)zb->zb_object, + (longlong_t)zb->zb_level, + (longlong_t)zb->zb_blkid); + bzero(&dp->dp_scrub_bookmark, sizeof (*zb)); + } + } + + if (BP_GET_LEVEL(bp) > 0) { + uint32_t flags = ARC_WAIT; + int i; + blkptr_t *cbp; + int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT; + + err = arc_read(NULL, dp->dp_spa, bp, pbuf, + arc_getbuf_func, &buf, + ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); + if (err) { + mutex_enter(&dp->dp_spa->spa_scrub_lock); + dp->dp_spa->spa_scrub_errors++; + mutex_exit(&dp->dp_spa->spa_scrub_lock); + return; + } + cbp = buf->b_data; + + for (i = 0; i < epb; i++, cbp++) { + zbookmark_t czb; + + SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object, + zb->zb_level - 1, + zb->zb_blkid * epb + i); + scrub_visitbp(dp, dnp, buf, cbp, &czb); + } + } else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) { + uint32_t flags = ARC_WAIT; + dnode_phys_t *child_dnp; + int i, j; + int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT; + + err = arc_read(NULL, dp->dp_spa, bp, pbuf, + arc_getbuf_func, &buf, + ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); + if (err) { + mutex_enter(&dp->dp_spa->spa_scrub_lock); + dp->dp_spa->spa_scrub_errors++; + mutex_exit(&dp->dp_spa->spa_scrub_lock); + return; + } + child_dnp = buf->b_data; + + for (i = 0; i < epb; i++, child_dnp++) { + for (j = 0; j < child_dnp->dn_nblkptr; j++) { + zbookmark_t czb; + + SET_BOOKMARK(&czb, zb->zb_objset, + zb->zb_blkid * epb + i, + child_dnp->dn_nlevels - 1, j); + scrub_visitbp(dp, child_dnp, buf, + &child_dnp->dn_blkptr[j], &czb); + } + } + } else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) { + uint32_t flags = ARC_WAIT; + objset_phys_t *osp; + int j; + + err = arc_read_nolock(NULL, dp->dp_spa, bp, + arc_getbuf_func, &buf, + ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); + if (err) { + mutex_enter(&dp->dp_spa->spa_scrub_lock); + dp->dp_spa->spa_scrub_errors++; + mutex_exit(&dp->dp_spa->spa_scrub_lock); + return; + } + + osp = buf->b_data; + + traverse_zil(dp, &osp->os_zil_header); + + for (j = 0; j < osp->os_meta_dnode.dn_nblkptr; j++) { + zbookmark_t czb; + + SET_BOOKMARK(&czb, zb->zb_objset, 0, + osp->os_meta_dnode.dn_nlevels - 1, j); + scrub_visitbp(dp, &osp->os_meta_dnode, buf, + &osp->os_meta_dnode.dn_blkptr[j], &czb); + } + } + + (void) scrub_funcs[dp->dp_scrub_func](dp, bp, zb); + if (buf) + (void) arc_buf_remove_ref(buf, &buf); +} + +static void +scrub_visit_rootbp(dsl_pool_t *dp, dsl_dataset_t *ds, blkptr_t *bp) +{ + zbookmark_t zb; + + SET_BOOKMARK(&zb, ds ? ds->ds_object : 0, 0, -1, 0); + scrub_visitbp(dp, NULL, NULL, bp, &zb); +} + +void +dsl_pool_ds_destroyed(dsl_dataset_t *ds, dmu_tx_t *tx) +{ + dsl_pool_t *dp = ds->ds_dir->dd_pool; + + if (dp->dp_scrub_func == SCRUB_FUNC_NONE) + return; + + if (dp->dp_scrub_bookmark.zb_objset == ds->ds_object) { + SET_BOOKMARK(&dp->dp_scrub_bookmark, -1, 0, 0, 0); + } else if (zap_remove_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds->ds_object, tx) != 0) { + return; + } + + if (ds->ds_phys->ds_next_snap_obj != 0) { + VERIFY(zap_add_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds->ds_phys->ds_next_snap_obj, tx) == 0); + } + ASSERT3U(ds->ds_phys->ds_num_children, <=, 1); +} + +void +dsl_pool_ds_snapshotted(dsl_dataset_t *ds, dmu_tx_t *tx) +{ + dsl_pool_t *dp = ds->ds_dir->dd_pool; + + if (dp->dp_scrub_func == SCRUB_FUNC_NONE) + return; + + ASSERT(ds->ds_phys->ds_prev_snap_obj != 0); + + if (dp->dp_scrub_bookmark.zb_objset == ds->ds_object) { + dp->dp_scrub_bookmark.zb_objset = + ds->ds_phys->ds_prev_snap_obj; + } else if (zap_remove_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds->ds_object, tx) == 0) { + VERIFY(zap_add_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds->ds_phys->ds_prev_snap_obj, tx) == 0); + } +} + +void +dsl_pool_ds_clone_swapped(dsl_dataset_t *ds1, dsl_dataset_t *ds2, dmu_tx_t *tx) +{ + dsl_pool_t *dp = ds1->ds_dir->dd_pool; + + if (dp->dp_scrub_func == SCRUB_FUNC_NONE) + return; + + if (dp->dp_scrub_bookmark.zb_objset == ds1->ds_object) { + dp->dp_scrub_bookmark.zb_objset = ds2->ds_object; + } else if (dp->dp_scrub_bookmark.zb_objset == ds2->ds_object) { + dp->dp_scrub_bookmark.zb_objset = ds1->ds_object; + } + + if (zap_remove_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds1->ds_object, tx) == 0) { + int err = zap_add_int(dp->dp_meta_objset, + dp->dp_scrub_queue_obj, ds2->ds_object, tx); + VERIFY(err == 0 || err == EEXIST); + if (err == EEXIST) { + /* Both were there to begin with */ + VERIFY(0 == zap_add_int(dp->dp_meta_objset, + dp->dp_scrub_queue_obj, ds1->ds_object, tx)); + } + } else if (zap_remove_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds2->ds_object, tx) == 0) { + VERIFY(0 == zap_add_int(dp->dp_meta_objset, + dp->dp_scrub_queue_obj, ds1->ds_object, tx)); + } +} + +struct enqueue_clones_arg { + dmu_tx_t *tx; + uint64_t originobj; +}; + +/* ARGSUSED */ +static int +enqueue_clones_cb(spa_t *spa, uint64_t dsobj, const char *dsname, void *arg) +{ + struct enqueue_clones_arg *eca = arg; + dsl_dataset_t *ds; + int err; + dsl_pool_t *dp; + + err = dsl_dataset_hold_obj(spa->spa_dsl_pool, dsobj, FTAG, &ds); + if (err) + return (err); + dp = ds->ds_dir->dd_pool; + + if (ds->ds_dir->dd_phys->dd_origin_obj == eca->originobj) { + while (ds->ds_phys->ds_prev_snap_obj != eca->originobj) { + dsl_dataset_t *prev; + err = dsl_dataset_hold_obj(dp, + ds->ds_phys->ds_prev_snap_obj, FTAG, &prev); + + dsl_dataset_rele(ds, FTAG); + if (err) + return (err); + ds = prev; + } + VERIFY(zap_add_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds->ds_object, eca->tx) == 0); + } + dsl_dataset_rele(ds, FTAG); + return (0); +} + +static void +scrub_visitds(dsl_pool_t *dp, uint64_t dsobj, dmu_tx_t *tx) +{ + dsl_dataset_t *ds; + uint64_t min_txg_save; + + VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds)); + + /* + * Iterate over the bps in this ds. + */ + min_txg_save = dp->dp_scrub_min_txg; + dp->dp_scrub_min_txg = + MAX(dp->dp_scrub_min_txg, ds->ds_phys->ds_prev_snap_txg); + scrub_visit_rootbp(dp, ds, &ds->ds_phys->ds_bp); + dp->dp_scrub_min_txg = min_txg_save; + + if (dp->dp_scrub_pausing) + goto out; + + /* + * Add descendent datasets to work queue. + */ + if (ds->ds_phys->ds_next_snap_obj != 0) { + VERIFY(zap_add_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds->ds_phys->ds_next_snap_obj, tx) == 0); + } + if (ds->ds_phys->ds_num_children > 1) { + if (spa_version(dp->dp_spa) < SPA_VERSION_DSL_SCRUB) { + struct enqueue_clones_arg eca; + eca.tx = tx; + eca.originobj = ds->ds_object; + + (void) dmu_objset_find_spa(ds->ds_dir->dd_pool->dp_spa, + NULL, enqueue_clones_cb, &eca, DS_FIND_CHILDREN); + } else { + VERIFY(zap_join(dp->dp_meta_objset, + ds->ds_phys->ds_next_clones_obj, + dp->dp_scrub_queue_obj, tx) == 0); + } + } + +out: + dsl_dataset_rele(ds, FTAG); +} + +/* ARGSUSED */ +static int +enqueue_cb(spa_t *spa, uint64_t dsobj, const char *dsname, void *arg) +{ + dmu_tx_t *tx = arg; + dsl_dataset_t *ds; + int err; + dsl_pool_t *dp; + + err = dsl_dataset_hold_obj(spa->spa_dsl_pool, dsobj, FTAG, &ds); + if (err) + return (err); + + dp = ds->ds_dir->dd_pool; + + while (ds->ds_phys->ds_prev_snap_obj != 0) { + dsl_dataset_t *prev; + err = dsl_dataset_hold_obj(dp, ds->ds_phys->ds_prev_snap_obj, + FTAG, &prev); + if (err) { + dsl_dataset_rele(ds, FTAG); + return (err); + } + + /* + * If this is a clone, we don't need to worry about it for now. + */ + if (prev->ds_phys->ds_next_snap_obj != ds->ds_object) { + dsl_dataset_rele(ds, FTAG); + dsl_dataset_rele(prev, FTAG); + return (0); + } + dsl_dataset_rele(ds, FTAG); + ds = prev; + } + + VERIFY(zap_add_int(dp->dp_meta_objset, dp->dp_scrub_queue_obj, + ds->ds_object, tx) == 0); + dsl_dataset_rele(ds, FTAG); + return (0); +} + +void +dsl_pool_scrub_sync(dsl_pool_t *dp, dmu_tx_t *tx) +{ + zap_cursor_t zc; + zap_attribute_t za; + boolean_t complete = B_TRUE; + + if (dp->dp_scrub_func == SCRUB_FUNC_NONE) + return; + + /* If the spa is not fully loaded, don't bother. */ + if (dp->dp_spa->spa_load_state != SPA_LOAD_NONE) + return; + + if (dp->dp_scrub_restart) { + enum scrub_func func = dp->dp_scrub_func; + dp->dp_scrub_restart = B_FALSE; + dsl_pool_scrub_setup_sync(dp, &func, kcred, tx); + } + + if (dp->dp_spa->spa_root_vdev->vdev_stat.vs_scrub_type == 0) { + /* + * We must have resumed after rebooting; reset the vdev + * stats to know that we're doing a scrub (although it + * will think we're just starting now). + */ + vdev_scrub_stat_update(dp->dp_spa->spa_root_vdev, + dp->dp_scrub_min_txg ? POOL_SCRUB_RESILVER : + POOL_SCRUB_EVERYTHING, B_FALSE); + } + + dp->dp_scrub_pausing = B_FALSE; + dp->dp_scrub_start_time = lbolt64; + dp->dp_scrub_isresilver = (dp->dp_scrub_min_txg != 0); + dp->dp_spa->spa_scrub_active = B_TRUE; + + if (dp->dp_scrub_bookmark.zb_objset == 0) { + /* First do the MOS & ORIGIN */ + scrub_visit_rootbp(dp, NULL, &dp->dp_meta_rootbp); + if (dp->dp_scrub_pausing) + goto out; + + if (spa_version(dp->dp_spa) < SPA_VERSION_DSL_SCRUB) { + VERIFY(0 == dmu_objset_find_spa(dp->dp_spa, + NULL, enqueue_cb, tx, DS_FIND_CHILDREN)); + } else { + scrub_visitds(dp, dp->dp_origin_snap->ds_object, tx); + } + ASSERT(!dp->dp_scrub_pausing); + } else if (dp->dp_scrub_bookmark.zb_objset != -1ULL) { + /* + * If we were paused, continue from here. Note if the + * ds we were paused on was deleted, the zb_objset will + * be -1, so we will skip this and find a new objset + * below. + */ + scrub_visitds(dp, dp->dp_scrub_bookmark.zb_objset, tx); + if (dp->dp_scrub_pausing) + goto out; + } + + /* + * In case we were paused right at the end of the ds, zero the + * bookmark so we don't think that we're still trying to resume. + */ + bzero(&dp->dp_scrub_bookmark, sizeof (zbookmark_t)); + + /* keep pulling things out of the zap-object-as-queue */ + while (zap_cursor_init(&zc, dp->dp_meta_objset, dp->dp_scrub_queue_obj), + zap_cursor_retrieve(&zc, &za) == 0) { + VERIFY(0 == zap_remove(dp->dp_meta_objset, + dp->dp_scrub_queue_obj, za.za_name, tx)); + scrub_visitds(dp, za.za_first_integer, tx); + if (dp->dp_scrub_pausing) + break; + zap_cursor_fini(&zc); + } + zap_cursor_fini(&zc); + if (dp->dp_scrub_pausing) + goto out; + + /* done. */ + + dsl_pool_scrub_cancel_sync(dp, &complete, kcred, tx); + return; +out: + VERIFY(0 == zap_update(dp->dp_meta_objset, + DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_BOOKMARK, sizeof (uint64_t), 4, + &dp->dp_scrub_bookmark, tx)); + VERIFY(0 == zap_update(dp->dp_meta_objset, + DMU_POOL_DIRECTORY_OBJECT, + DMU_POOL_SCRUB_ERRORS, sizeof (uint64_t), 1, + &dp->dp_spa->spa_scrub_errors, tx)); + + /* XXX this is scrub-clean specific */ + mutex_enter(&dp->dp_spa->spa_scrub_lock); + while (dp->dp_spa->spa_scrub_inflight > 0) { + cv_wait(&dp->dp_spa->spa_scrub_io_cv, + &dp->dp_spa->spa_scrub_lock); + } + mutex_exit(&dp->dp_spa->spa_scrub_lock); +} + +void +dsl_pool_scrub_restart(dsl_pool_t *dp) +{ + mutex_enter(&dp->dp_scrub_cancel_lock); + dp->dp_scrub_restart = B_TRUE; + mutex_exit(&dp->dp_scrub_cancel_lock); +} + +/* + * scrub consumers + */ + +static void +count_block(zfs_all_blkstats_t *zab, const blkptr_t *bp) +{ + int i; + + /* + * If we resume after a reboot, zab will be NULL; don't record + * incomplete stats in that case. + */ + if (zab == NULL) + return; + + for (i = 0; i < 4; i++) { + int l = (i < 2) ? BP_GET_LEVEL(bp) : DN_MAX_LEVELS; + int t = (i & 1) ? BP_GET_TYPE(bp) : DMU_OT_TOTAL; + zfs_blkstat_t *zb = &zab->zab_type[l][t]; + int equal; + + zb->zb_count++; + zb->zb_asize += BP_GET_ASIZE(bp); + zb->zb_lsize += BP_GET_LSIZE(bp); + zb->zb_psize += BP_GET_PSIZE(bp); + zb->zb_gangs += BP_COUNT_GANG(bp); + + switch (BP_GET_NDVAS(bp)) { + case 2: + if (DVA_GET_VDEV(&bp->blk_dva[0]) == + DVA_GET_VDEV(&bp->blk_dva[1])) + zb->zb_ditto_2_of_2_samevdev++; + break; + case 3: + equal = (DVA_GET_VDEV(&bp->blk_dva[0]) == + DVA_GET_VDEV(&bp->blk_dva[1])) + + (DVA_GET_VDEV(&bp->blk_dva[0]) == + DVA_GET_VDEV(&bp->blk_dva[2])) + + (DVA_GET_VDEV(&bp->blk_dva[1]) == + DVA_GET_VDEV(&bp->blk_dva[2])); + if (equal == 1) + zb->zb_ditto_2_of_3_samevdev++; + else if (equal == 3) + zb->zb_ditto_3_of_3_samevdev++; + break; + } + } +} + +static void +dsl_pool_scrub_clean_done(zio_t *zio) +{ + spa_t *spa = zio->io_spa; + + zio_data_buf_free(zio->io_data, zio->io_size); + + mutex_enter(&spa->spa_scrub_lock); + spa->spa_scrub_inflight--; + cv_broadcast(&spa->spa_scrub_io_cv); + + if (zio->io_error && (zio->io_error != ECKSUM || + !(zio->io_flags & ZIO_FLAG_SPECULATIVE))) + spa->spa_scrub_errors++; + mutex_exit(&spa->spa_scrub_lock); +} + +static int +dsl_pool_scrub_clean_cb(dsl_pool_t *dp, + const blkptr_t *bp, const zbookmark_t *zb) +{ + size_t size = BP_GET_LSIZE(bp); + int d; + spa_t *spa = dp->dp_spa; + boolean_t needs_io; + int zio_flags = ZIO_FLAG_SCRUB_THREAD | ZIO_FLAG_CANFAIL; + int zio_priority; + + count_block(dp->dp_blkstats, bp); + + if (dp->dp_scrub_isresilver == 0) { + /* It's a scrub */ + zio_flags |= ZIO_FLAG_SCRUB; + zio_priority = ZIO_PRIORITY_SCRUB; + needs_io = B_TRUE; + } else { + /* It's a resilver */ + zio_flags |= ZIO_FLAG_RESILVER; + zio_priority = ZIO_PRIORITY_RESILVER; + needs_io = B_FALSE; + } + + /* If it's an intent log block, failure is expected. */ + if (zb->zb_level == -1 && BP_GET_TYPE(bp) != DMU_OT_OBJSET) + zio_flags |= ZIO_FLAG_SPECULATIVE; + + for (d = 0; d < BP_GET_NDVAS(bp); d++) { + vdev_t *vd = vdev_lookup_top(spa, + DVA_GET_VDEV(&bp->blk_dva[d])); + + /* + * Keep track of how much data we've examined so that + * zpool(1M) status can make useful progress reports. + */ + mutex_enter(&vd->vdev_stat_lock); + vd->vdev_stat.vs_scrub_examined += + DVA_GET_ASIZE(&bp->blk_dva[d]); + mutex_exit(&vd->vdev_stat_lock); + + /* if it's a resilver, this may not be in the target range */ + if (!needs_io) { + if (DVA_GET_GANG(&bp->blk_dva[d])) { + /* + * Gang members may be spread across multiple + * vdevs, so the best we can do is look at the + * pool-wide DTL. + * XXX -- it would be better to change our + * allocation policy to ensure that this can't + * happen. + */ + vd = spa->spa_root_vdev; + } + needs_io = vdev_dtl_contains(&vd->vdev_dtl_map, + bp->blk_birth, 1); + } + } + + if (needs_io && !zfs_no_scrub_io) { + void *data = zio_data_buf_alloc(size); + + mutex_enter(&spa->spa_scrub_lock); + while (spa->spa_scrub_inflight >= spa->spa_scrub_maxinflight) + cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock); + spa->spa_scrub_inflight++; + mutex_exit(&spa->spa_scrub_lock); + + zio_nowait(zio_read(NULL, spa, bp, data, size, + dsl_pool_scrub_clean_done, NULL, zio_priority, + zio_flags, zb)); + } + + /* do not relocate this block */ + return (0); +} + +int +dsl_pool_scrub_clean(dsl_pool_t *dp) +{ + /* + * Purge all vdev caches. We do this here rather than in sync + * context because this requires a writer lock on the spa_config + * lock, which we can't do from sync context. The + * spa_scrub_reopen flag indicates that vdev_open() should not + * attempt to start another scrub. + */ + spa_config_enter(dp->dp_spa, SCL_ALL, FTAG, RW_WRITER); + dp->dp_spa->spa_scrub_reopen = B_TRUE; + vdev_reopen(dp->dp_spa->spa_root_vdev); + dp->dp_spa->spa_scrub_reopen = B_FALSE; + spa_config_exit(dp->dp_spa, SCL_ALL, FTAG); + + return (dsl_pool_scrub_setup(dp, SCRUB_FUNC_CLEAN)); +} diff --git a/zfs/lib/libzpool/dsl_synctask.c b/zfs/lib/libzpool/dsl_synctask.c index 305a23bf2..21100225a 100644 --- a/zfs/lib/libzpool/dsl_synctask.c +++ b/zfs/lib/libzpool/dsl_synctask.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)dsl_synctask.c 1.5 07/10/29 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/fletcher.c b/zfs/lib/libzpool/fletcher.c index 299d70c11..edda3c9a9 100644 --- a/zfs/lib/libzpool/fletcher.c +++ b/zfs/lib/libzpool/fletcher.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)fletcher.c 1.2 06/03/03 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/gzip.c b/zfs/lib/libzpool/gzip.c index 94c76042d..b257d4af7 100644 --- a/zfs/lib/libzpool/gzip.c +++ b/zfs/lib/libzpool/gzip.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)gzip.c 1.1 07/03/22 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/arc.h b/zfs/lib/libzpool/include/sys/arc.h similarity index 79% rename from zfs/lib/libzcommon/include/sys/arc.h rename to zfs/lib/libzpool/include/sys/arc.h index 54b7c94e3..749bf53e5 100644 --- a/zfs/lib/libzcommon/include/sys/arc.h +++ b/zfs/lib/libzpool/include/sys/arc.h @@ -26,8 +26,6 @@ #ifndef _SYS_ARC_H #define _SYS_ARC_H -#pragma ident "@(#)arc.h 1.12 08/03/20 SMI" - #include #ifdef __cplusplus @@ -50,6 +48,7 @@ arc_done_func_t arc_getbuf_func; struct arc_buf { arc_buf_hdr_t *b_hdr; arc_buf_t *b_next; + krwlock_t b_lock; void *b_data; arc_evict_func_t *b_efunc; void *b_private; @@ -67,6 +66,7 @@ typedef enum arc_buf_contents { #define ARC_NOWAIT (1 << 2) /* perform I/O asynchronously */ #define ARC_PREFETCH (1 << 3) /* I/O is a prefetch */ #define ARC_CACHED (1 << 4) /* I/O was already in cache */ +#define ARC_L2CACHE (1 << 5) /* cache in L2ARC */ void arc_space_consume(uint64_t space); void arc_space_return(uint64_t space); @@ -86,13 +86,25 @@ void arc_buf_thaw(arc_buf_t *buf); int arc_referenced(arc_buf_t *buf); #endif -int arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_byteswap_func_t *swap, +typedef struct writeprops { + dmu_object_type_t wp_type; + uint8_t wp_level; + uint8_t wp_copies; + uint8_t wp_dncompress, wp_oscompress; + uint8_t wp_dnchecksum, wp_oschecksum; +} writeprops_t; + +void write_policy(spa_t *spa, const writeprops_t *wp, zio_prop_t *zp); +int arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf, + arc_done_func_t *done, void *private, int priority, int zio_flags, + uint32_t *arc_flags, const zbookmark_t *zb); +int arc_read_nolock(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_done_func_t *done, void *private, int priority, int flags, - uint32_t *arc_flags, zbookmark_t *zb); -zio_t *arc_write(zio_t *pio, spa_t *spa, int checksum, int compress, - int ncopies, uint64_t txg, blkptr_t *bp, arc_buf_t *buf, + uint32_t *arc_flags, const zbookmark_t *zb); +zio_t *arc_write(zio_t *pio, spa_t *spa, const writeprops_t *wp, + boolean_t l2arc, uint64_t txg, blkptr_t *bp, arc_buf_t *buf, arc_done_func_t *ready, arc_done_func_t *done, void *private, int priority, - int flags, zbookmark_t *zb); + int zio_flags, const zbookmark_t *zb); int arc_free(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, zio_done_func_t *done, void *private, uint32_t arc_flags); int arc_tryread(spa_t *spa, blkptr_t *bp, void *data); @@ -113,8 +125,11 @@ void arc_fini(void); void l2arc_add_vdev(spa_t *spa, vdev_t *vd, uint64_t start, uint64_t end); void l2arc_remove_vdev(vdev_t *vd); +boolean_t l2arc_vdev_present(vdev_t *vd); void l2arc_init(void); void l2arc_fini(void); +void l2arc_start(void); +void l2arc_stop(void); #ifdef __cplusplus } diff --git a/zfs/lib/libzcommon/include/sys/bplist.h b/zfs/lib/libzpool/include/sys/bplist.h similarity index 88% rename from zfs/lib/libzcommon/include/sys/bplist.h rename to zfs/lib/libzpool/include/sys/bplist.h index 518314ad0..cdb93a6c3 100644 --- a/zfs/lib/libzcommon/include/sys/bplist.h +++ b/zfs/lib/libzpool/include/sys/bplist.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_BPLIST_H #define _SYS_BPLIST_H -#pragma ident "@(#)bplist.h 1.3 06/05/24 SMI" - #include #include #include @@ -75,12 +73,14 @@ extern int bplist_open(bplist_t *bpl, objset_t *mos, uint64_t object); extern void bplist_close(bplist_t *bpl); extern boolean_t bplist_empty(bplist_t *bpl); extern int bplist_iterate(bplist_t *bpl, uint64_t *itorp, blkptr_t *bp); -extern int bplist_enqueue(bplist_t *bpl, blkptr_t *bp, dmu_tx_t *tx); -extern void bplist_enqueue_deferred(bplist_t *bpl, blkptr_t *bp); +extern int bplist_enqueue(bplist_t *bpl, const blkptr_t *bp, dmu_tx_t *tx); +extern void bplist_enqueue_deferred(bplist_t *bpl, const blkptr_t *bp); extern void bplist_sync(bplist_t *bpl, dmu_tx_t *tx); extern void bplist_vacate(bplist_t *bpl, dmu_tx_t *tx); extern int bplist_space(bplist_t *bpl, uint64_t *usedp, uint64_t *compp, uint64_t *uncompp); +extern int bplist_space_birthrange(bplist_t *bpl, + uint64_t mintxg, uint64_t maxtxg, uint64_t *dasizep); #ifdef __cplusplus } diff --git a/zfs/lib/libzcommon/include/sys/dbuf.h b/zfs/lib/libzpool/include/sys/dbuf.h similarity index 89% rename from zfs/lib/libzcommon/include/sys/dbuf.h rename to zfs/lib/libzpool/include/sys/dbuf.h index cca3a3fcd..75ce27264 100644 --- a/zfs/lib/libzcommon/include/sys/dbuf.h +++ b/zfs/lib/libzpool/include/sys/dbuf.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DBUF_H #define _SYS_DBUF_H -#pragma ident "@(#)dbuf.h 1.10 07/08/26 SMI" - #include #include #include @@ -55,19 +53,23 @@ extern "C" { #define DB_RF_CACHED (1 << 5) /* - * The state transition diagram for dbufs looks like: + * The simplified state transition diagram for dbufs looks like: * * +----> READ ----+ * | | * | V * (alloc)-->UNCACHED CACHED-->EVICTING-->(free) - * | ^ - * | | - * +----> FILL ----+ + * | ^ ^ + * | | | + * +----> FILL ----+ | + * | | + * | | + * +--------> NOFILL -------+ */ typedef enum dbuf_states { DB_UNCACHED, DB_FILL, + DB_NOFILL, DB_READ, DB_CACHED, DB_EVICTING @@ -258,8 +260,8 @@ dmu_buf_impl_t *dbuf_find(struct dnode *dn, uint8_t level, uint64_t blkid); int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags); void dbuf_will_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx); -void dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx); void dbuf_fill_done(dmu_buf_impl_t *db, dmu_tx_t *tx); +void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx); void dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx); void dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx); dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx); @@ -271,7 +273,7 @@ void dbuf_setdirty(dmu_buf_impl_t *db, dmu_tx_t *tx); void dbuf_unoverride(dbuf_dirty_record_t *dr); void dbuf_sync_list(list_t *list, dmu_tx_t *tx); -void dbuf_free_range(struct dnode *dn, uint64_t blkid, uint64_t nblks, +void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end, struct dmu_tx *); void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx); @@ -279,10 +281,21 @@ void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx); void dbuf_init(void); void dbuf_fini(void); -#define DBUF_GET_BUFC_TYPE(db) \ - ((((db)->db_level > 0) || \ - (dmu_ot[(db)->db_dnode->dn_type].ot_metadata)) ? \ - ARC_BUFC_METADATA : ARC_BUFC_DATA); +#define DBUF_IS_METADATA(db) \ + ((db)->db_level > 0 || dmu_ot[(db)->db_dnode->dn_type].ot_metadata) + +#define DBUF_GET_BUFC_TYPE(db) \ + (DBUF_IS_METADATA(db) ? ARC_BUFC_METADATA : ARC_BUFC_DATA) + +#define DBUF_IS_CACHEABLE(db) \ + ((db)->db_objset->os_primary_cache == ZFS_CACHE_ALL || \ + (DBUF_IS_METADATA(db) && \ + ((db)->db_objset->os_primary_cache == ZFS_CACHE_METADATA))) + +#define DBUF_IS_L2CACHEABLE(db) \ + ((db)->db_objset->os_secondary_cache == ZFS_CACHE_ALL || \ + (DBUF_IS_METADATA(db) && \ + ((db)->db_objset->os_secondary_cache == ZFS_CACHE_METADATA))) #ifdef ZFS_DEBUG diff --git a/zfs/lib/libzcommon/include/sys/dmu.h b/zfs/lib/libzpool/include/sys/dmu.h similarity index 95% rename from zfs/lib/libzcommon/include/sys/dmu.h rename to zfs/lib/libzpool/include/sys/dmu.h index 2f1cdfc7f..3b1e5c8fb 100644 --- a/zfs/lib/libzcommon/include/sys/dmu.h +++ b/zfs/lib/libzpool/include/sys/dmu.h @@ -26,8 +26,6 @@ #ifndef _SYS_DMU_H #define _SYS_DMU_H -#pragma ident "@(#)dmu.h 1.38 08/04/27 SMI" - /* * This file describes the interface that the DMU provides for its * consumers. @@ -114,6 +112,8 @@ typedef enum dmu_object_type { DMU_OT_SYSACL, /* SYSACL */ DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */ DMU_OT_FUID_SIZE, /* FUID table size UINT64 */ + DMU_OT_NEXT_CLONES, /* ZAP */ + DMU_OT_SCRUB_QUEUE, /* ZAP */ DMU_OT_NUMTYPES } dmu_object_type_t; @@ -136,12 +136,11 @@ void zfs_oldacl_byteswap(void *buf, size_t size); void zfs_acl_byteswap(void *buf, size_t size); void zfs_znode_byteswap(void *buf, size_t size); -#define DS_MODE_NONE 0 /* invalid, to aid debugging */ -#define DS_MODE_STANDARD 1 /* normal access, no special needs */ -#define DS_MODE_PRIMARY 2 /* the "main" access, e.g. a mount */ -#define DS_MODE_EXCLUSIVE 3 /* exclusive access, e.g. to destroy */ -#define DS_MODE_LEVELS 4 -#define DS_MODE_LEVEL(x) ((x) & (DS_MODE_LEVELS - 1)) +#define DS_MODE_NOHOLD 0 /* internal use only */ +#define DS_MODE_USER 1 /* simple access, no special needs */ +#define DS_MODE_OWNER 2 /* the "main" access, e.g. a mount */ +#define DS_MODE_TYPE_MASK 0x3 +#define DS_MODE_TYPE(x) ((x) & DS_MODE_TYPE_MASK) #define DS_MODE_READONLY 0x8 #define DS_MODE_IS_READONLY(x) ((x) & DS_MODE_READONLY) #define DS_MODE_INCONSISTENT 0x10 @@ -155,6 +154,7 @@ void zfs_znode_byteswap(void *buf, size_t size); * operation, including metadata. */ #define DMU_MAX_ACCESS (10<<20) /* 10MB */ +#define DMU_MAX_DELETEBLKCNT (20480) /* ~5MB of indirect blocks */ /* * Public routines to create, destroy, open, and close objsets. @@ -202,6 +202,19 @@ typedef void dmu_buf_evict_func_t(struct dmu_buf *db, void *user_ptr); #define DMU_POOL_PROPS "pool_props" #define DMU_POOL_L2CACHE "l2cache" +/* 4x8 zbookmark_t */ +#define DMU_POOL_SCRUB_BOOKMARK "scrub_bookmark" +/* 1x8 zap obj DMU_OT_SCRUB_QUEUE */ +#define DMU_POOL_SCRUB_QUEUE "scrub_queue" +/* 1x8 txg */ +#define DMU_POOL_SCRUB_MIN_TXG "scrub_min_txg" +/* 1x8 txg */ +#define DMU_POOL_SCRUB_MAX_TXG "scrub_max_txg" +/* 1x4 enum scrub_func */ +#define DMU_POOL_SCRUB_FUNC "scrub_func" +/* 1x8 count */ +#define DMU_POOL_SCRUB_ERRORS "scrub_errors" + /* * Allocate an object from this objset. The range of object numbers * available is (0, DN_MAX_OBJECT). Object 0 is the meta-dnode. @@ -422,6 +435,9 @@ void dmu_tx_commit(dmu_tx_t *tx); */ int dmu_free_range(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_tx_t *tx); +int dmu_free_long_range(objset_t *os, uint64_t object, uint64_t offset, + uint64_t size); +int dmu_free_object(objset_t *os, uint64_t object); /* * Convenience functions. @@ -433,6 +449,8 @@ int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, void *buf); void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, const void *buf, dmu_tx_t *tx); +void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, + dmu_tx_t *tx); int dmu_read_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size); int dmu_write_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size, dmu_tx_t *tx); diff --git a/zfs/lib/libzcommon/include/sys/dmu_impl.h b/zfs/lib/libzpool/include/sys/dmu_impl.h similarity index 96% rename from zfs/lib/libzcommon/include/sys/dmu_impl.h rename to zfs/lib/libzpool/include/sys/dmu_impl.h index c06872bce..96ce688e1 100644 --- a/zfs/lib/libzcommon/include/sys/dmu_impl.h +++ b/zfs/lib/libzpool/include/sys/dmu_impl.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DMU_IMPL_H #define _SYS_DMU_IMPL_H -#pragma ident "@(#)dmu_impl.h 1.2 07/02/02 SMI" - #include #include #include @@ -51,7 +49,7 @@ extern "C" { * XXX try to improve evicting path? * * dp_config_rwlock > os_obj_lock > dn_struct_rwlock > - * dn_dbufs_mtx > hash_mutexes > db_mtx > leafs + * dn_dbufs_mtx > hash_mutexes > db_mtx > dd_lock > leafs * * dp_config_rwlock * must be held before: everything @@ -177,7 +175,10 @@ extern "C" { * dmu_tx_try_assign: dn_notxholds(cv) * dmu_tx_unassign: none * - * dd_lock (leaf) + * dd_lock + * must be held before: + * ds_lock + * ancestors' dd_lock * protects: * dd_prop_cbs * dd_sync_* @@ -207,13 +208,14 @@ extern "C" { * dnode_setdirty: none (dn_dirtyblksz, os_*_dnodes) * dnode_free: none (dn_dirtyblksz, os_*_dnodes) * - * ds_lock (leaf) + * ds_lock * protects: * ds_user_ptr * ds_user_evice_func * ds_open_refcount * ds_snapname * ds_phys accounting + * ds_reserved * held from: * dsl_dataset_* * diff --git a/zfs/lib/libzcommon/include/sys/dmu_objset.h b/zfs/lib/libzpool/include/sys/dmu_objset.h similarity index 88% rename from zfs/lib/libzcommon/include/sys/dmu_objset.h rename to zfs/lib/libzpool/include/sys/dmu_objset.h index 2a4ff6cad..15df29a17 100644 --- a/zfs/lib/libzcommon/include/sys/dmu_objset.h +++ b/zfs/lib/libzpool/include/sys/dmu_objset.h @@ -26,7 +26,7 @@ #ifndef _SYS_DMU_OBJSET_H #define _SYS_DMU_OBJSET_H -#pragma ident "@(#)dmu_objset.h 1.13 08/04/27 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -69,12 +69,13 @@ typedef struct objset_impl { uint8_t os_checksum; /* can change, under dsl_dir's locks */ uint8_t os_compress; /* can change, under dsl_dir's locks */ uint8_t os_copies; /* can change, under dsl_dir's locks */ - uint8_t os_md_checksum; - uint8_t os_md_compress; + uint8_t os_primary_cache; /* can change, under dsl_dir's locks */ + uint8_t os_secondary_cache; /* can change, under dsl_dir's locks */ /* no lock needed: */ struct dmu_tx *os_synctx; /* XXX sketchy */ blkptr_t *os_rootbp; + zil_header_t os_zil_header; /* Protected by os_obj_lock */ kmutex_t os_obj_lock; @@ -94,6 +95,10 @@ typedef struct objset_impl { #define DMU_META_DNODE_OBJECT 0 +#define DMU_OS_IS_L2CACHEABLE(os) \ + ((os)->os_secondary_cache == ZFS_CACHE_ALL || \ + (os)->os_secondary_cache == ZFS_CACHE_METADATA) + /* called from zpl */ int dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, objset_t **osp); @@ -111,6 +116,8 @@ void dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp, uint64_t dmu_objset_fsid_guid(objset_t *os); int dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags); +int dmu_objset_find_spa(spa_t *spa, const char *name, + int func(spa_t *, uint64_t, const char *, void *), void *arg, int flags); void dmu_objset_byteswap(void *buf, size_t size); int dmu_objset_evict_dbufs(objset_t *os); diff --git a/zfs/lib/libzcommon/include/sys/rprwlock.h b/zfs/lib/libzpool/include/sys/dmu_traverse.h similarity index 56% rename from zfs/lib/libzcommon/include/sys/rprwlock.h rename to zfs/lib/libzpool/include/sys/dmu_traverse.h index 723b9548d..3e0268911 100644 --- a/zfs/lib/libzcommon/include/sys/rprwlock.h +++ b/zfs/lib/libzpool/include/sys/dmu_traverse.h @@ -19,43 +19,39 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#ifndef _SYS_RPRWLOCK_H -#define _SYS_RPRWLOCK_H +#ifndef _SYS_DMU_TRAVERSE_H +#define _SYS_DMU_TRAVERSE_H - - -#include -#include #include -#include +#include +#include #ifdef __cplusplus extern "C" { #endif -typedef struct rprwlock { - kmutex_t rw_lock; - kthread_t *rw_writer; - kcondvar_t rw_cv; - refcount_t rw_count; -} rprwlock_t; +struct dnode_phys; +struct dsl_dataset; -void rprw_init(rprwlock_t *rwl); -void rprw_destroy(rprwlock_t *rwl); -void rprw_enter_read(rprwlock_t *rwl, void *tag); -void rprw_enter_write(rprwlock_t *rwl, void *tag); -void rprw_enter(rprwlock_t *rwl, krw_t rw, void *tag); -void rprw_exit(rprwlock_t *rwl, void *tag); -boolean_t rprw_held(rprwlock_t *rwl, krw_t rw); -#define RPRW_READ_HELD(x) rprw_held(x, RW_READER) -#define RPRW_WRITE_HELD(x) rprw_held(x, RW_WRITER) +typedef int (blkptr_cb_t)(spa_t *spa, blkptr_t *bp, + const zbookmark_t *zb, const struct dnode_phys *dnp, void *arg); + +#define TRAVERSE_PRE (1<<0) +#define TRAVERSE_POST (1<<1) +#define TRAVERSE_PREFETCH_METADATA (1<<2) +#define TRAVERSE_PREFETCH_DATA (1<<3) +#define TRAVERSE_PREFETCH (TRAVERSE_PREFETCH_METADATA | TRAVERSE_PREFETCH_DATA) + +int traverse_dataset(struct dsl_dataset *ds, uint64_t txg_start, + int flags, blkptr_cb_t func, void *arg); +int traverse_pool(spa_t *spa, blkptr_cb_t func, void *arg); #ifdef __cplusplus } #endif -#endif /* _SYS_RPRWLOCK_H */ +#endif /* _SYS_DMU_TRAVERSE_H */ diff --git a/zfs/lib/libzcommon/include/sys/dmu_tx.h b/zfs/lib/libzpool/include/sys/dmu_tx.h similarity index 95% rename from zfs/lib/libzcommon/include/sys/dmu_tx.h rename to zfs/lib/libzpool/include/sys/dmu_tx.h index 3c4ec9acd..2727daaaa 100644 --- a/zfs/lib/libzcommon/include/sys/dmu_tx.h +++ b/zfs/lib/libzpool/include/sys/dmu_tx.h @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DMU_TX_H #define _SYS_DMU_TX_H -#pragma ident "@(#)dmu_tx.h 1.6 07/10/29 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -89,6 +89,8 @@ typedef struct dmu_tx_hold { uint64_t txh_space_tofree; uint64_t txh_space_tooverwrite; uint64_t txh_space_tounref; + uint64_t txh_memory_tohold; + uint64_t txh_fudge; #ifdef ZFS_DEBUG enum dmu_tx_hold_type txh_type; uint64_t txh_arg1; diff --git a/zfs/lib/libzcommon/include/sys/dmu_zfetch.h b/zfs/lib/libzpool/include/sys/dmu_zfetch.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/dmu_zfetch.h rename to zfs/lib/libzpool/include/sys/dmu_zfetch.h index 93d59c75c..c94bced93 100644 --- a/zfs/lib/libzcommon/include/sys/dmu_zfetch.h +++ b/zfs/lib/libzpool/include/sys/dmu_zfetch.h @@ -26,7 +26,7 @@ #ifndef _DFETCH_H #define _DFETCH_H -#pragma ident "@(#)dmu_zfetch.h 1.2 06/07/17 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/lib/libzcommon/include/sys/dnode.h b/zfs/lib/libzpool/include/sys/dnode.h similarity index 95% rename from zfs/lib/libzcommon/include/sys/dnode.h rename to zfs/lib/libzpool/include/sys/dnode.h index fa13e583b..c79ff48a6 100644 --- a/zfs/lib/libzcommon/include/sys/dnode.h +++ b/zfs/lib/libzpool/include/sys/dnode.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DNODE_H #define _SYS_DNODE_H -#pragma ident "@(#)dnode.h 1.12 07/08/26 SMI" - #include #include #include @@ -41,11 +39,18 @@ extern "C" { #endif /* - * Flags. + * dnode_hold() flags. */ #define DNODE_MUST_BE_ALLOCATED 1 #define DNODE_MUST_BE_FREE 2 +/* + * dnode_next_offset() flags. + */ +#define DNODE_FIND_HOLE 1 +#define DNODE_FIND_BACKWARDS 2 +#define DNODE_FIND_HAVELOCK 4 + /* * Fixed constants. */ @@ -223,12 +228,12 @@ void dnode_clear_range(dnode_t *dn, uint64_t blkid, uint64_t nblks, dmu_tx_t *tx); void dnode_diduse_space(dnode_t *dn, int64_t space); void dnode_willuse_space(dnode_t *dn, int64_t space, dmu_tx_t *tx); -void dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx); +void dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx, boolean_t); uint64_t dnode_block_freed(dnode_t *dn, uint64_t blkid); void dnode_init(void); void dnode_fini(void); -int dnode_next_offset(dnode_t *dn, boolean_t hole, uint64_t *off, int minlvl, - uint64_t blkfill, uint64_t txg); +int dnode_next_offset(dnode_t *dn, int flags, uint64_t *off, + int minlvl, uint64_t blkfill, uint64_t txg); void dnode_evict_dbufs(dnode_t *dn); #ifdef ZFS_DEBUG diff --git a/zfs/lib/libzcommon/include/sys/dsl_dataset.h b/zfs/lib/libzpool/include/sys/dsl_dataset.h similarity index 77% rename from zfs/lib/libzcommon/include/sys/dsl_dataset.h rename to zfs/lib/libzpool/include/sys/dsl_dataset.h index 09404c5c6..8665aec2d 100644 --- a/zfs/lib/libzcommon/include/sys/dsl_dataset.h +++ b/zfs/lib/libzpool/include/sys/dsl_dataset.h @@ -26,8 +26,6 @@ #ifndef _SYS_DSL_DATASET_H #define _SYS_DSL_DATASET_H -#pragma ident "@(#)dsl_dataset.h 1.16 08/04/27 SMI" - #include #include #include @@ -47,6 +45,8 @@ struct dsl_pool; typedef void dsl_dataset_evict_func_t(struct dsl_dataset *, void *); #define DS_FLAG_INCONSISTENT (1ULL<<0) +#define DS_IS_INCONSISTENT(ds) \ + ((ds)->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) /* * NB: nopromote can not yet be set, but we want support for it in this * on-disk version, so that we don't need to upgrade for it later. It @@ -69,15 +69,15 @@ typedef void dsl_dataset_evict_func_t(struct dsl_dataset *, void *); #define DS_FLAG_CI_DATASET (1ULL<<16) typedef struct dsl_dataset_phys { - uint64_t ds_dir_obj; - uint64_t ds_prev_snap_obj; + uint64_t ds_dir_obj; /* DMU_OT_DSL_DIR */ + uint64_t ds_prev_snap_obj; /* DMU_OT_DSL_DATASET */ uint64_t ds_prev_snap_txg; - uint64_t ds_next_snap_obj; - uint64_t ds_snapnames_zapobj; /* zap obj of snaps; ==0 for snaps */ + uint64_t ds_next_snap_obj; /* DMU_OT_DSL_DATASET */ + uint64_t ds_snapnames_zapobj; /* DMU_OT_DSL_DS_SNAP_MAP 0 for snaps */ uint64_t ds_num_children; /* clone/snap children; ==0 for head */ uint64_t ds_creation_time; /* seconds since 1970 */ uint64_t ds_creation_txg; - uint64_t ds_deadlist_obj; + uint64_t ds_deadlist_obj; /* DMU_OT_BPLIST */ uint64_t ds_used_bytes; uint64_t ds_compressed_bytes; uint64_t ds_uncompressed_bytes; @@ -89,9 +89,11 @@ typedef struct dsl_dataset_phys { */ uint64_t ds_fsid_guid; uint64_t ds_guid; - uint64_t ds_flags; + uint64_t ds_flags; /* DS_FLAG_* */ blkptr_t ds_bp; - uint64_t ds_pad[8]; /* pad out to 320 bytes for good measure */ + uint64_t ds_next_clones_obj; /* DMU_OT_DSL_CLONES */ + uint64_t ds_props_obj; /* DMU_OT_DSL_PROPS for snaps */ + uint64_t ds_pad[6]; /* pad out to 320 bytes for good measure */ } dsl_dataset_phys_t; typedef struct dsl_dataset { @@ -102,8 +104,9 @@ typedef struct dsl_dataset { uint64_t ds_object; uint64_t ds_fsid_guid; - /* only used in syncing context: */ - struct dsl_dataset *ds_prev; /* only valid for non-snapshots */ + /* only used in syncing context, only valid for non-snapshots: */ + struct dsl_dataset *ds_prev; + uint64_t ds_origin_txg; /* has internal locking: */ bplist_t ds_deadlist; @@ -119,7 +122,13 @@ typedef struct dsl_dataset { kmutex_t ds_lock; void *ds_user_ptr; dsl_dataset_evict_func_t *ds_user_evict_func; - uint64_t ds_open_refcount; + + /* + * ds_owner is protected by the ds_rwlock and the ds_lock + */ + krwlock_t ds_rwlock; + kcondvar_t ds_exclusive_cv; + void *ds_owner; /* no locking; only for making guesses */ uint64_t ds_trysnap_txg; @@ -140,21 +149,24 @@ typedef struct dsl_dataset { #define DS_UNIQUE_IS_ACCURATE(ds) \ (((ds)->ds_phys->ds_flags & DS_FLAG_UNIQUE_ACCURATE) != 0) -int dsl_dataset_open_spa(spa_t *spa, const char *name, int mode, - void *tag, dsl_dataset_t **dsp); -int dsl_dataset_open(const char *name, int mode, void *tag, +int dsl_dataset_hold(const char *name, void *tag, dsl_dataset_t **dsp); +int dsl_dataset_hold_obj(struct dsl_pool *dp, uint64_t dsobj, + void *tag, dsl_dataset_t **); +int dsl_dataset_own(const char *name, int flags, void *owner, dsl_dataset_t **dsp); -int dsl_dataset_open_obj(struct dsl_pool *dp, uint64_t dsobj, - const char *tail, int mode, void *tag, dsl_dataset_t **); +int dsl_dataset_own_obj(struct dsl_pool *dp, uint64_t dsobj, + int flags, void *owner, dsl_dataset_t **); void dsl_dataset_name(dsl_dataset_t *ds, char *name); -void dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag); -void dsl_dataset_downgrade(dsl_dataset_t *ds, int oldmode, int newmode); -boolean_t dsl_dataset_tryupgrade(dsl_dataset_t *ds, int oldmode, int newmode); -uint64_t dsl_dataset_create_sync_impl(dsl_dir_t *dd, dsl_dataset_t *origin, +void dsl_dataset_rele(dsl_dataset_t *ds, void *tag); +void dsl_dataset_disown(dsl_dataset_t *ds, void *owner); +void dsl_dataset_drop_ref(dsl_dataset_t *ds, void *tag); +boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, boolean_t inconsistentok, + void *owner); +void dsl_dataset_make_exclusive(dsl_dataset_t *ds, void *owner); +uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname, + dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *); +uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, uint64_t flags, dmu_tx_t *tx); -uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, - const char *lastname, dsl_dataset_t *origin, uint64_t flags, - cred_t *, dmu_tx_t *); int dsl_dataset_destroy(dsl_dataset_t *ds, void *tag); int dsl_snapshots_destroy(char *fsname, char *snapname); dsl_checkfunc_t dsl_dataset_destroy_check; @@ -181,7 +193,7 @@ boolean_t dsl_dataset_modified_since_lastsnap(dsl_dataset_t *ds); void dsl_dataset_sync(dsl_dataset_t *os, zio_t *zio, dmu_tx_t *tx); void dsl_dataset_block_born(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx); -void dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, +int dsl_dataset_block_kill(dsl_dataset_t *ds, blkptr_t *bp, zio_t *pio, dmu_tx_t *tx); int dsl_dataset_block_freeable(dsl_dataset_t *ds, uint64_t blk_birth); uint64_t dsl_dataset_prev_snap_txg(dsl_dataset_t *ds); @@ -194,9 +206,6 @@ void dsl_dataset_space(dsl_dataset_t *ds, uint64_t *usedobjsp, uint64_t *availobjsp); uint64_t dsl_dataset_fsid_guid(dsl_dataset_t *ds); -void dsl_dataset_create_root(struct dsl_pool *dp, uint64_t *ddobjp, - dmu_tx_t *tx); - int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf); int dsl_dataset_check_quota(dsl_dataset_t *ds, boolean_t check_quota, @@ -207,6 +216,8 @@ void dsl_dataset_set_quota_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx); int dsl_dataset_set_reservation(const char *dsname, uint64_t reservation); void dsl_dataset_set_flags(dsl_dataset_t *ds, uint64_t flags); +int64_t dsl_dataset_new_refreservation(dsl_dataset_t *ds, uint64_t reservation, + dmu_tx_t *tx); #ifdef ZFS_DEBUG #define dprintf_ds(ds, fmt, ...) do { \ diff --git a/zfs/lib/libzcommon/include/sys/dsl_deleg.h b/zfs/lib/libzpool/include/sys/dsl_deleg.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/dsl_deleg.h rename to zfs/lib/libzpool/include/sys/dsl_deleg.h index 8d3cf902a..a29e44e67 100644 --- a/zfs/lib/libzcommon/include/sys/dsl_deleg.h +++ b/zfs/lib/libzpool/include/sys/dsl_deleg.h @@ -26,7 +26,7 @@ #ifndef _SYS_DSL_DELEG_H #define _SYS_DSL_DELEG_H -#pragma ident "@(#)dsl_deleg.h 1.4 07/10/25 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/dsl_dir.h b/zfs/lib/libzpool/include/sys/dsl_dir.h similarity index 84% rename from zfs/lib/libzcommon/include/sys/dsl_dir.h rename to zfs/lib/libzpool/include/sys/dsl_dir.h index 7c3d0873d..86b9636ce 100644 --- a/zfs/lib/libzcommon/include/sys/dsl_dir.h +++ b/zfs/lib/libzpool/include/sys/dsl_dir.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DSL_DIR_H #define _SYS_DSL_DIR_H -#pragma ident "@(#)dsl_dir.h 1.10 07/10/29 SMI" - #include #include #include @@ -40,6 +38,17 @@ extern "C" { struct dsl_dataset; +typedef enum dd_used { + DD_USED_HEAD, + DD_USED_SNAP, + DD_USED_CHILD, + DD_USED_CHILD_RSRV, + DD_USED_REFRSRV, + DD_USED_NUM +} dd_used_t; + +#define DD_FLAG_USED_BREAKDOWN (1<<0) + typedef struct dsl_dir_phys { uint64_t dd_creation_time; /* not actually used */ uint64_t dd_head_dataset_obj; @@ -59,7 +68,9 @@ typedef struct dsl_dir_phys { uint64_t dd_reserved; uint64_t dd_props_zapobj; uint64_t dd_deleg_zapobj; /* dataset delegation permissions */ - uint64_t dd_pad[20]; /* pad out to 256 bytes for good measure */ + uint64_t dd_flags; + uint64_t dd_used_breakdown[DD_USED_NUM]; + uint64_t dd_pad[14]; /* pad out to 256 bytes for good measure */ } dsl_dir_phys_t; struct dsl_dir { @@ -79,9 +90,6 @@ struct dsl_dir { kmutex_t dd_lock; list_t dd_prop_cbs; /* list of dsl_prop_cb_record_t's */ - /* Accounting */ - /* reflects any changes to dd_phys->dd_used_bytes made this syncing */ - int64_t dd_used_bytes; /* gross estimate of space used by in-flight tx's */ uint64_t dd_tempreserved[TXG_SIZE]; /* amount of space we expect to write; == amount of dirty data */ @@ -100,8 +108,8 @@ int dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, void dsl_dir_name(dsl_dir_t *dd, char *buf); int dsl_dir_namelen(dsl_dir_t *dd); int dsl_dir_is_private(dsl_dir_t *dd); -uint64_t dsl_dir_create_sync(dsl_dir_t *pds, const char *name, dmu_tx_t *tx); -void dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx); +uint64_t dsl_dir_create_sync(dsl_pool_t *dp, dsl_dir_t *pds, + const char *name, dmu_tx_t *tx); dsl_checkfunc_t dsl_dir_destroy_check; dsl_syncfunc_t dsl_dir_destroy_sync; void dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv); @@ -114,16 +122,22 @@ int dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t mem, dmu_tx_t *tx); void dsl_dir_tempreserve_clear(void *tr_cookie, dmu_tx_t *tx); void dsl_dir_willuse_space(dsl_dir_t *dd, int64_t space, dmu_tx_t *tx); -void dsl_dir_diduse_space(dsl_dir_t *dd, +void dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type, int64_t used, int64_t compressed, int64_t uncompressed, dmu_tx_t *tx); +void dsl_dir_transfer_space(dsl_dir_t *dd, int64_t delta, + dd_used_t oldtype, dd_used_t newtype, dmu_tx_t *tx); int dsl_dir_set_quota(const char *ddname, uint64_t quota); int dsl_dir_set_reservation(const char *ddname, uint64_t reservation); int dsl_dir_rename(dsl_dir_t *dd, const char *newname); int dsl_dir_transfer_possible(dsl_dir_t *sdd, dsl_dir_t *tdd, uint64_t space); int dsl_dir_set_reservation_check(void *arg1, void *arg2, dmu_tx_t *tx); +boolean_t dsl_dir_is_clone(dsl_dir_t *dd); +void dsl_dir_new_refreservation(dsl_dir_t *dd, struct dsl_dataset *ds, + uint64_t reservation, cred_t *cr, dmu_tx_t *tx); /* internal reserved dir name */ #define MOS_DIR_NAME "$MOS" +#define ORIGIN_DIR_NAME "$ORIGIN" #ifdef ZFS_DEBUG #define dprintf_dd(dd, fmt, ...) do { \ diff --git a/zfs/lib/libzcommon/include/sys/dsl_pool.h b/zfs/lib/libzpool/include/sys/dsl_pool.h similarity index 57% rename from zfs/lib/libzcommon/include/sys/dsl_pool.h rename to zfs/lib/libzpool/include/sys/dsl_pool.h index 2b4f52c3b..3bb4ad4ef 100644 --- a/zfs/lib/libzcommon/include/sys/dsl_pool.h +++ b/zfs/lib/libzpool/include/sys/dsl_pool.h @@ -26,12 +26,12 @@ #ifndef _SYS_DSL_POOL_H #define _SYS_DSL_POOL_H -#pragma ident "@(#)dsl_pool.h 1.5 08/03/20 SMI" - #include #include #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -39,6 +39,35 @@ extern "C" { struct objset; struct dsl_dir; +struct dsl_dataset; +struct dsl_pool; +struct dmu_tx; + +enum scrub_func { + SCRUB_FUNC_NONE, + SCRUB_FUNC_CLEAN, + SCRUB_FUNC_NUMFUNCS +}; + +/* These macros are for indexing into the zfs_all_blkstats_t. */ +#define DMU_OT_DEFERRED DMU_OT_NONE +#define DMU_OT_TOTAL DMU_OT_NUMTYPES + +typedef struct zfs_blkstat { + uint64_t zb_count; + uint64_t zb_asize; + uint64_t zb_lsize; + uint64_t zb_psize; + uint64_t zb_gangs; + uint64_t zb_ditto_2_of_2_samevdev; + uint64_t zb_ditto_2_of_3_samevdev; + uint64_t zb_ditto_3_of_3_samevdev; +} zfs_blkstat_t; + +typedef struct zfs_all_blkstats { + zfs_blkstat_t zab_type[DN_MAX_LEVELS + 1][DMU_OT_TOTAL + 1]; +} zfs_all_blkstats_t; + typedef struct dsl_pool { /* Immutable */ @@ -46,11 +75,14 @@ typedef struct dsl_pool { struct objset *dp_meta_objset; struct dsl_dir *dp_root_dir; struct dsl_dir *dp_mos_dir; + struct dsl_dataset *dp_origin_snap; uint64_t dp_root_dir_obj; /* No lock needed - sync context only */ blkptr_t dp_meta_rootbp; list_t dp_synced_datasets; + hrtime_t dp_read_overhead; + uint64_t dp_throughput; uint64_t dp_write_limit; /* Uses dp_lock */ @@ -58,6 +90,17 @@ typedef struct dsl_pool { uint64_t dp_space_towrite[TXG_SIZE]; uint64_t dp_tempreserved[TXG_SIZE]; + enum scrub_func dp_scrub_func; + uint64_t dp_scrub_queue_obj; + uint64_t dp_scrub_min_txg; + uint64_t dp_scrub_max_txg; + zbookmark_t dp_scrub_bookmark; + boolean_t dp_scrub_pausing; + boolean_t dp_scrub_isresilver; + uint64_t dp_scrub_start_time; + kmutex_t dp_scrub_cancel_lock; /* protects dp_scrub_restart */ + boolean_t dp_scrub_restart; + /* Has its own locking */ tx_state_t dp_tx; txg_list_t dp_dirty_datasets; @@ -71,11 +114,13 @@ typedef struct dsl_pool { * nobody else could possibly have it for write. */ krwlock_t dp_config_rwlock; + + zfs_all_blkstats_t *dp_blkstats; } dsl_pool_t; int dsl_pool_open(spa_t *spa, uint64_t txg, dsl_pool_t **dpp); void dsl_pool_close(dsl_pool_t *dp); -dsl_pool_t *dsl_pool_create(spa_t *spa, uint64_t txg); +dsl_pool_t *dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg); void dsl_pool_sync(dsl_pool_t *dp, uint64_t txg); void dsl_pool_zil_clean(dsl_pool_t *dp); int dsl_pool_sync_context(dsl_pool_t *dp); @@ -84,6 +129,19 @@ int dsl_pool_tempreserve_space(dsl_pool_t *dp, uint64_t space, dmu_tx_t *tx); void dsl_pool_tempreserve_clear(dsl_pool_t *dp, int64_t space, dmu_tx_t *tx); void dsl_pool_memory_pressure(dsl_pool_t *dp); void dsl_pool_willuse_space(dsl_pool_t *dp, int64_t space, dmu_tx_t *tx); +int dsl_free(zio_t *pio, dsl_pool_t *dp, uint64_t txg, const blkptr_t *bpp, + zio_done_func_t *done, void *private, uint32_t arc_flags); +void dsl_pool_ds_destroyed(struct dsl_dataset *ds, struct dmu_tx *tx); +void dsl_pool_ds_snapshotted(struct dsl_dataset *ds, struct dmu_tx *tx); +void dsl_pool_ds_clone_swapped(struct dsl_dataset *ds1, struct dsl_dataset *ds2, + struct dmu_tx *tx); +void dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx); +void dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx); + +int dsl_pool_scrub_cancel(dsl_pool_t *dp); +int dsl_pool_scrub_clean(dsl_pool_t *dp); +void dsl_pool_scrub_sync(dsl_pool_t *dp, dmu_tx_t *tx); +void dsl_pool_scrub_restart(dsl_pool_t *dp); #ifdef __cplusplus } diff --git a/zfs/lib/libzcommon/include/sys/dsl_prop.h b/zfs/lib/libzpool/include/sys/dsl_prop.h similarity index 86% rename from zfs/lib/libzcommon/include/sys/dsl_prop.h rename to zfs/lib/libzpool/include/sys/dsl_prop.h index 5995bae13..d66caa86c 100644 --- a/zfs/lib/libzcommon/include/sys/dsl_prop.h +++ b/zfs/lib/libzpool/include/sys/dsl_prop.h @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DSL_PROP_H #define _SYS_DSL_PROP_H -#pragma ident "@(#)dsl_prop.h 1.6 07/10/29 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -37,6 +37,7 @@ extern "C" { #endif struct dsl_dataset; +struct dsl_dir; /* The callback func may not call into the DMU or DSL! */ typedef void (dsl_prop_changed_cb_t)(void *arg, uint64_t newval); @@ -59,14 +60,14 @@ int dsl_prop_get(const char *ddname, const char *propname, int intsz, int numints, void *buf, char *setpoint); int dsl_prop_get_integer(const char *ddname, const char *propname, uint64_t *valuep, char *setpoint); -int dsl_prop_get_all(objset_t *os, nvlist_t **nvp); -int dsl_prop_get_ds_locked(dsl_dir_t *dd, const char *propname, +int dsl_prop_get_all(objset_t *os, nvlist_t **nvp, boolean_t local); +int dsl_prop_get_ds(struct dsl_dataset *ds, const char *propname, + int intsz, int numints, void *buf, char *setpoint); +int dsl_prop_get_dd(struct dsl_dir *dd, const char *propname, int intsz, int numints, void *buf, char *setpoint); int dsl_prop_set(const char *ddname, const char *propname, int intsz, int numints, const void *buf); -int dsl_prop_set_dd(dsl_dir_t *dd, const char *propname, - int intsz, int numints, const void *buf); void dsl_prop_set_uint64_sync(dsl_dir_t *dd, const char *name, uint64_t val, cred_t *cr, dmu_tx_t *tx); diff --git a/zfs/lib/libzcommon/include/sys/dsl_synctask.h b/zfs/lib/libzpool/include/sys/dsl_synctask.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/dsl_synctask.h rename to zfs/lib/libzpool/include/sys/dsl_synctask.h index fa1bc23fd..4995bfe5a 100644 --- a/zfs/lib/libzcommon/include/sys/dsl_synctask.h +++ b/zfs/lib/libzpool/include/sys/dsl_synctask.h @@ -26,7 +26,7 @@ #ifndef _SYS_DSL_SYNCTASK_H #define _SYS_DSL_SYNCTASK_H -#pragma ident "@(#)dsl_synctask.h 1.3 07/06/29 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/metaslab.h b/zfs/lib/libzpool/include/sys/metaslab.h similarity index 90% rename from zfs/lib/libzcommon/include/sys/metaslab.h rename to zfs/lib/libzpool/include/sys/metaslab.h index d6b0df925..1c9d89e8f 100644 --- a/zfs/lib/libzcommon/include/sys/metaslab.h +++ b/zfs/lib/libzpool/include/sys/metaslab.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_METASLAB_H #define _SYS_METASLAB_H -#pragma ident "@(#)metaslab.h 1.6 07/06/21 SMI" - #include #include #include @@ -47,9 +45,12 @@ extern void metaslab_fini(metaslab_t *msp); extern void metaslab_sync(metaslab_t *msp, uint64_t txg); extern void metaslab_sync_done(metaslab_t *msp, uint64_t txg); +#define METASLAB_HINTBP_FAVOR 0x0 +#define METASLAB_HINTBP_AVOID 0x1 +#define METASLAB_GANG_HEADER 0x2 + extern int metaslab_alloc(spa_t *spa, metaslab_class_t *mc, uint64_t psize, - blkptr_t *bp, int ncopies, uint64_t txg, blkptr_t *hintbp, - boolean_t hintbp_avoid); + blkptr_t *bp, int ncopies, uint64_t txg, blkptr_t *hintbp, int flags); extern void metaslab_free(spa_t *spa, const blkptr_t *bp, uint64_t txg, boolean_t now); extern int metaslab_claim(spa_t *spa, const blkptr_t *bp, uint64_t txg); diff --git a/zfs/lib/libzcommon/include/sys/metaslab_impl.h b/zfs/lib/libzpool/include/sys/metaslab_impl.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/metaslab_impl.h rename to zfs/lib/libzpool/include/sys/metaslab_impl.h index 35e30c118..5980cbc84 100644 --- a/zfs/lib/libzcommon/include/sys/metaslab_impl.h +++ b/zfs/lib/libzpool/include/sys/metaslab_impl.h @@ -26,7 +26,7 @@ #ifndef _SYS_METASLAB_IMPL_H #define _SYS_METASLAB_IMPL_H -#pragma ident "@(#)metaslab_impl.h 1.2 06/04/02 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/refcount.h b/zfs/lib/libzpool/include/sys/refcount.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/refcount.h rename to zfs/lib/libzpool/include/sys/refcount.h index a78704549..d3fe7b1f8 100644 --- a/zfs/lib/libzcommon/include/sys/refcount.h +++ b/zfs/lib/libzpool/include/sys/refcount.h @@ -26,7 +26,7 @@ #ifndef _SYS_REFCOUNT_H #define _SYS_REFCOUNT_H -#pragma ident "@(#)refcount.h 1.3 07/08/02 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/rrwlock.h b/zfs/lib/libzpool/include/sys/rrwlock.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/rrwlock.h rename to zfs/lib/libzpool/include/sys/rrwlock.h index 9d15e69cf..19a43c97f 100644 --- a/zfs/lib/libzcommon/include/sys/rrwlock.h +++ b/zfs/lib/libzpool/include/sys/rrwlock.h @@ -26,7 +26,7 @@ #ifndef _SYS_RR_RW_LOCK_H #define _SYS_RR_RW_LOCK_H -#pragma ident "@(#)rrwlock.h 1.1 07/10/24 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { diff --git a/zfs/lib/libzcommon/include/sys/spa.h b/zfs/lib/libzpool/include/sys/spa.h similarity index 89% rename from zfs/lib/libzcommon/include/sys/spa.h rename to zfs/lib/libzpool/include/sys/spa.h index 0c5eb10c3..24b3ca447 100644 --- a/zfs/lib/libzcommon/include/sys/spa.h +++ b/zfs/lib/libzpool/include/sys/spa.h @@ -26,8 +26,6 @@ #ifndef _SYS_SPA_H #define _SYS_SPA_H -#pragma ident "@(#)spa.h 1.31 08/04/09 SMI" - #include #include #include @@ -46,7 +44,6 @@ typedef struct spa spa_t; typedef struct vdev vdev_t; typedef struct metaslab metaslab_t; typedef struct zilog zilog_t; -typedef struct traverse_handle traverse_handle_t; typedef struct spa_aux_vdev spa_aux_vdev_t; struct dsl_pool; @@ -88,6 +85,11 @@ struct dsl_pool; #define SPA_BLOCKSIZES (SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1) +/* + * Size of block to hold the configuration data (a packed nvlist) + */ +#define SPA_CONFIG_BLOCKSIZE (1 << 14) + /* * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB. * The ASIZE encoding should be at least 64 times larger (6 more bits) @@ -259,7 +261,6 @@ typedef struct blkptr { ((zc1).zc_word[2] - (zc2).zc_word[2]) | \ ((zc1).zc_word[3] - (zc2).zc_word[3]))) - #define DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0) #define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \ @@ -275,7 +276,7 @@ typedef struct blkptr { #define BP_IS_HOLE(bp) ((bp)->blk_birth == 0) #define BP_IS_OLDER(bp, txg) (!BP_IS_HOLE(bp) && (bp)->blk_birth < (txg)) -#define BP_ZERO_DVAS(bp) \ +#define BP_ZERO(bp) \ { \ (bp)->blk_dva[0].dva_word[0] = 0; \ (bp)->blk_dva[0].dva_word[1] = 0; \ @@ -283,20 +284,17 @@ typedef struct blkptr { (bp)->blk_dva[1].dva_word[1] = 0; \ (bp)->blk_dva[2].dva_word[0] = 0; \ (bp)->blk_dva[2].dva_word[1] = 0; \ - (bp)->blk_birth = 0; \ -} - -#define BP_ZERO(bp) \ -{ \ - BP_ZERO_DVAS(bp) \ (bp)->blk_prop = 0; \ (bp)->blk_pad[0] = 0; \ (bp)->blk_pad[1] = 0; \ (bp)->blk_pad[2] = 0; \ + (bp)->blk_birth = 0; \ (bp)->blk_fill = 0; \ ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0); \ } +#define BLK_FILL_ALREADY_FREED (-1ULL) + /* * Note: the byteorder is either 0 or -1, both of which are palindromes. * This simplifies the endianness handling a bit. @@ -325,27 +323,29 @@ extern int spa_open(const char *pool, spa_t **, void *tag); extern int spa_get_stats(const char *pool, nvlist_t **config, char *altroot, size_t buflen); extern int spa_create(const char *pool, nvlist_t *config, nvlist_t *props, - const char *history_str); -extern void spa_check_rootconf(char *devpath, char **the_dev_p, - nvlist_t **the_conf_p, uint64_t *the_txg_p); + const char *history_str, nvlist_t *zplprops); +extern int spa_check_rootconf(char *devpath, char *devid, + nvlist_t **bestconf, uint64_t *besttxg); extern boolean_t spa_rootdev_validate(nvlist_t *nv); -extern int spa_import_rootpool(char *devpath); +extern int spa_import_rootpool(char *devpath, char *devid); extern int spa_import(const char *pool, nvlist_t *config, nvlist_t *props); +extern int spa_import_faulted(const char *, nvlist_t *, nvlist_t *); extern nvlist_t *spa_tryimport(nvlist_t *tryconfig); extern int spa_destroy(char *pool); -extern int spa_export(char *pool, nvlist_t **oldconfig); +extern int spa_export(char *pool, nvlist_t **oldconfig, boolean_t force); extern int spa_reset(char *pool); extern void spa_async_request(spa_t *spa, int flag); +extern void spa_async_unrequest(spa_t *spa, int flag); extern void spa_async_suspend(spa_t *spa); extern void spa_async_resume(spa_t *spa); extern spa_t *spa_inject_addref(char *pool); extern void spa_inject_delref(spa_t *spa); -#define SPA_ASYNC_REMOVE 0x01 -#define SPA_ASYNC_RESILVER_DONE 0x02 -#define SPA_ASYNC_SCRUB 0x04 -#define SPA_ASYNC_RESILVER 0x08 -#define SPA_ASYNC_CONFIG_UPDATE 0x10 +#define SPA_ASYNC_CONFIG_UPDATE 0x01 +#define SPA_ASYNC_REMOVE 0x02 +#define SPA_ASYNC_PROBE 0x04 +#define SPA_ASYNC_RESILVER_DONE 0x08 +#define SPA_ASYNC_RESILVER 0x10 /* device manipulation */ extern int spa_vdev_add(spa_t *spa, nvlist_t *nvroot); @@ -358,7 +358,7 @@ extern int spa_vdev_setpath(spa_t *spa, uint64_t guid, const char *newpath); /* spare state (which is global across all pools) */ extern void spa_spare_add(vdev_t *vd); extern void spa_spare_remove(vdev_t *vd); -extern boolean_t spa_spare_exists(uint64_t guid, uint64_t *pool); +extern boolean_t spa_spare_exists(uint64_t guid, uint64_t *pool, int *refcnt); extern void spa_spare_activate(vdev_t *vd); /* L2ARC state (which is global across all pools) */ @@ -370,15 +370,15 @@ extern void spa_l2cache_drop(spa_t *spa); extern void spa_l2cache_space_update(vdev_t *vd, int64_t space, int64_t alloc); /* scrubbing */ -extern int spa_scrub(spa_t *spa, pool_scrub_type_t type, boolean_t force); -extern void spa_scrub_suspend(spa_t *spa); -extern void spa_scrub_resume(spa_t *spa); -extern void spa_scrub_restart(spa_t *spa, uint64_t txg); +extern int spa_scrub(spa_t *spa, pool_scrub_type_t type); /* spa syncing */ extern void spa_sync(spa_t *spa, uint64_t txg); /* only for DMU use */ extern void spa_sync_allpools(void); +/* spa namespace global mutex */ +extern kmutex_t spa_namespace_lock; + /* * SPA configuration functions in spa_config.c */ @@ -386,8 +386,7 @@ extern void spa_sync_allpools(void); #define SPA_CONFIG_UPDATE_POOL 0 #define SPA_CONFIG_UPDATE_VDEVS 1 -extern void spa_config_sync(void); -extern void spa_config_check(const char *, const char *); +extern void spa_config_sync(spa_t *, boolean_t, boolean_t); extern void spa_config_load(void); extern nvlist_t *spa_all_configs(uint64_t *); extern void spa_config_set(spa_t *spa, nvlist_t *config); @@ -411,18 +410,33 @@ extern void spa_open_ref(spa_t *spa, void *tag); extern void spa_close(spa_t *spa, void *tag); extern boolean_t spa_refcount_zero(spa_t *spa); -/* Pool configuration lock */ -extern void spa_config_enter(spa_t *spa, krw_t rw, void *tag); -extern void spa_config_exit(spa_t *spa, void *tag); -extern boolean_t spa_config_held(spa_t *spa, krw_t rw); +#define SCL_CONFIG 0x01 +#define SCL_STATE 0x02 +#define SCL_L2ARC 0x04 /* hack until L2ARC 2.0 */ +#define SCL_ALLOC 0x08 +#define SCL_ZIO 0x10 +#define SCL_FREE 0x20 +#define SCL_VDEV 0x40 +#define SCL_LOCKS 7 +#define SCL_ALL ((1 << SCL_LOCKS) - 1) +#define SCL_STATE_ALL (SCL_STATE | SCL_L2ARC | SCL_ZIO) + +/* Pool configuration locks */ +extern int spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw); +extern void spa_config_enter(spa_t *spa, int locks, void *tag, krw_t rw); +extern void spa_config_exit(spa_t *spa, int locks, void *tag); +extern int spa_config_held(spa_t *spa, int locks, krw_t rw); /* Pool vdev add/remove lock */ extern uint64_t spa_vdev_enter(spa_t *spa); extern int spa_vdev_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error); +/* Pool vdev state change lock */ +extern void spa_vdev_state_enter(spa_t *spa); +extern int spa_vdev_state_exit(spa_t *spa, vdev_t *vd, int error); + /* Accessor functions */ -extern krwlock_t *spa_traverse_rwlock(spa_t *spa); -extern int spa_traverse_wanted(spa_t *spa); +extern boolean_t spa_shutting_down(spa_t *spa); extern struct dsl_pool *spa_get_dsl(spa_t *spa); extern blkptr_t *spa_get_rootblkptr(spa_t *spa); extern void spa_set_rootblkptr(spa_t *spa, const blkptr_t *bp); @@ -433,7 +447,7 @@ extern uint64_t spa_guid(spa_t *spa); extern uint64_t spa_last_synced_txg(spa_t *spa); extern uint64_t spa_first_txg(spa_t *spa); extern uint64_t spa_version(spa_t *spa); -extern int spa_state(spa_t *spa); +extern pool_state_t spa_state(spa_t *spa); extern uint64_t spa_freeze_txg(spa_t *spa); extern uint64_t spa_get_alloc(spa_t *spa); extern uint64_t spa_get_space(spa_t *spa); @@ -443,6 +457,7 @@ extern uint64_t spa_version(spa_t *spa); extern int spa_max_replication(spa_t *spa); extern int spa_busy(void); extern uint8_t spa_get_failmode(spa_t *spa); +extern boolean_t spa_suspended(spa_t *spa); /* Miscellaneous support routines */ extern int spa_rename(const char *oldname, const char *newname); @@ -454,10 +469,12 @@ extern void sprintf_blkptr(char *buf, int len, const blkptr_t *bp); extern void spa_freeze(spa_t *spa); extern void spa_upgrade(spa_t *spa, uint64_t version); extern void spa_evict_all(void); -extern vdev_t *spa_lookup_by_guid(spa_t *spa, uint64_t guid); +extern vdev_t *spa_lookup_by_guid(spa_t *spa, uint64_t guid, + boolean_t l2cache); extern boolean_t spa_has_spare(spa_t *, uint64_t guid); extern uint64_t bp_get_dasize(spa_t *spa, const blkptr_t *bp); extern boolean_t spa_has_slogs(spa_t *spa); +extern boolean_t spa_is_root(spa_t *spa); /* history logging */ typedef enum history_log_type { @@ -489,7 +506,6 @@ struct zio; extern void spa_log_error(spa_t *spa, struct zio *zio); extern void zfs_ereport_post(const char *class, spa_t *spa, vdev_t *vd, struct zio *zio, uint64_t stateoroffset, uint64_t length); -extern void zfs_post_ok(spa_t *spa, vdev_t *vd); extern void zfs_post_remove(spa_t *spa, vdev_t *vd); extern void zfs_post_autoreplace(spa_t *spa, vdev_t *vd); extern uint64_t spa_get_errlog_size(spa_t *spa); diff --git a/zfs/lib/libzcommon/include/sys/spa_boot.h b/zfs/lib/libzpool/include/sys/spa_boot.h similarity index 83% rename from zfs/lib/libzcommon/include/sys/spa_boot.h rename to zfs/lib/libzpool/include/sys/spa_boot.h index cf38ca603..b56073b97 100644 --- a/zfs/lib/libzcommon/include/sys/spa_boot.h +++ b/zfs/lib/libzpool/include/sys/spa_boot.h @@ -26,7 +26,7 @@ #ifndef _SYS_SPA_BOOT_H #define _SYS_SPA_BOOT_H -#pragma ident "@(#)spa_boot.h 1.1 08/04/09 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include @@ -34,10 +34,9 @@ extern "C" { #endif -extern char *spa_get_bootfs(); -extern void spa_free_bootfs(char *bootfs); -extern int spa_get_rootconf(char *devpath, char **bestdev_p, - nvlist_t **bestconf_p); +extern char *spa_get_bootprop(char *prop); +extern void spa_free_bootprop(char *prop); +extern int spa_get_rootconf(char *devpath, char *devid, nvlist_t **bestconf_p); #ifdef __cplusplus } diff --git a/zfs/lib/libzcommon/include/sys/spa_impl.h b/zfs/lib/libzpool/include/sys/spa_impl.h similarity index 74% rename from zfs/lib/libzcommon/include/sys/spa_impl.h rename to zfs/lib/libzpool/include/sys/spa_impl.h index 42676ce85..8aeb414fe 100644 --- a/zfs/lib/libzcommon/include/sys/spa_impl.h +++ b/zfs/lib/libzpool/include/sys/spa_impl.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_SPA_IMPL_H #define _SYS_SPA_IMPL_H -#pragma ident "@(#)spa_impl.h 1.17 07/11/27 SMI" - #include #include #include @@ -70,29 +68,44 @@ struct spa_aux_vdev { typedef struct spa_config_lock { kmutex_t scl_lock; kthread_t *scl_writer; - uint16_t scl_write_wanted; + int scl_write_wanted; kcondvar_t scl_cv; refcount_t scl_count; } spa_config_lock_t; +typedef struct spa_config_dirent { + list_node_t scd_link; + char *scd_path; +} spa_config_dirent_t; + +typedef enum spa_log_state { + SPA_LOG_UNKNOWN = 0, /* unknown log state */ + SPA_LOG_MISSING, /* missing log(s) */ + SPA_LOG_CLEAR, /* clear the log(s) */ + SPA_LOG_GOOD, /* log(s) are good */ +} spa_log_state_t; + +enum zio_taskq_type { + ZIO_TASKQ_ISSUE = 0, + ZIO_TASKQ_INTERRUPT, + ZIO_TASKQ_TYPES +}; + struct spa { /* * Fields protected by spa_namespace_lock. */ - char *spa_name; /* pool name */ + char spa_name[MAXNAMELEN]; /* pool name */ avl_node_t spa_avl; /* node in spa_namespace_avl */ nvlist_t *spa_config; /* last synced config */ nvlist_t *spa_config_syncing; /* currently syncing config */ uint64_t spa_config_txg; /* txg of last config change */ - kmutex_t spa_config_cache_lock; /* for spa_config RW_READER */ int spa_sync_pass; /* iterate-to-convergence */ - int spa_state; /* pool state */ + pool_state_t spa_state; /* pool state */ int spa_inject_ref; /* injection references */ - uint8_t spa_traverse_wanted; /* traverse lock wanted */ uint8_t spa_sync_on; /* sync threads are running */ spa_load_state_t spa_load_state; /* current load operation */ - taskq_t *spa_zio_issue_taskq[ZIO_TYPES]; - taskq_t *spa_zio_intr_taskq[ZIO_TYPES]; + taskq_t *spa_zio_taskq[ZIO_TYPES][ZIO_TASKQ_TYPES]; dsl_pool_t *spa_dsl_pool; metaslab_class_t *spa_normal_class; /* normal data class */ metaslab_class_t *spa_log_class; /* intent log data class */ @@ -103,39 +116,35 @@ struct spa { txg_list_t spa_vdev_txg_list; /* per-txg dirty vdev list */ vdev_t *spa_root_vdev; /* top-level vdev container */ uint64_t spa_load_guid; /* initial guid for spa_load */ - list_t spa_dirty_list; /* vdevs with dirty labels */ + list_t spa_config_dirty_list; /* vdevs with dirty config */ + list_t spa_state_dirty_list; /* vdevs with dirty state */ spa_aux_vdev_t spa_spares; /* hot spares */ spa_aux_vdev_t spa_l2cache; /* L2ARC cache devices */ uint64_t spa_config_object; /* MOS object for pool config */ uint64_t spa_syncing_txg; /* txg currently syncing */ uint64_t spa_sync_bplist_obj; /* object for deferred frees */ bplist_t spa_sync_bplist; /* deferred-free bplist */ - krwlock_t spa_traverse_lock; /* traverse vs. spa_sync() */ uberblock_t spa_ubsync; /* last synced uberblock */ uberblock_t spa_uberblock; /* current uberblock */ kmutex_t spa_scrub_lock; /* resilver/scrub lock */ - kthread_t *spa_scrub_thread; /* scrub/resilver thread */ - traverse_handle_t *spa_scrub_th; /* scrub traverse handle */ - uint64_t spa_scrub_restart_txg; /* need to restart */ - uint64_t spa_scrub_mintxg; /* min txg we'll scrub */ - uint64_t spa_scrub_maxtxg; /* max txg we'll scrub */ uint64_t spa_scrub_inflight; /* in-flight scrub I/Os */ uint64_t spa_scrub_maxinflight; /* max in-flight scrub I/Os */ uint64_t spa_scrub_errors; /* scrub I/O error count */ - int spa_scrub_suspended; /* tell scrubber to suspend */ - kcondvar_t spa_scrub_cv; /* scrub thread state change */ kcondvar_t spa_scrub_io_cv; /* scrub I/O completion */ - uint8_t spa_scrub_stop; /* tell scrubber to stop */ uint8_t spa_scrub_active; /* active or suspended? */ uint8_t spa_scrub_type; /* type of scrub we're doing */ uint8_t spa_scrub_finished; /* indicator to rotate logs */ + uint8_t spa_scrub_started; /* started since last boot */ + uint8_t spa_scrub_reopen; /* scrub doing vdev_reopen */ kmutex_t spa_async_lock; /* protect async state */ kthread_t *spa_async_thread; /* thread doing async task */ int spa_async_suspended; /* async tasks suspended */ kcondvar_t spa_async_cv; /* wait for thread_exit() */ uint16_t spa_async_tasks; /* async task mask */ + kmutex_t spa_async_root_lock; /* protects async root count */ + uint64_t spa_async_root_count; /* number of async root zios */ + kcondvar_t spa_async_root_cv; /* notify when count == 0 */ char *spa_root; /* alternate root directory */ - kmutex_t spa_uberblock_lock; /* vdev_uberblock_load_done() */ uint64_t spa_ena; /* spa-wide ereport ENA */ boolean_t spa_last_open_failed; /* true if last open faled */ kmutex_t spa_errlog_lock; /* error log lock */ @@ -151,25 +160,34 @@ struct spa { kmutex_t spa_props_lock; /* property lock */ uint64_t spa_pool_props_object; /* object for properties */ uint64_t spa_bootfs; /* default boot filesystem */ - boolean_t spa_delegation; /* delegation on/off */ - char *spa_config_dir; /* cache file directory */ - char *spa_config_file; /* cache file name */ - list_t spa_zio_list; /* zio error list */ - kcondvar_t spa_zio_cv; /* resume I/O pipeline */ - kmutex_t spa_zio_lock; /* zio error lock */ - uint8_t spa_failmode; /* failure mode for the pool */ + uint64_t spa_failmode; /* failure mode for the pool */ + uint64_t spa_delegation; /* delegation on/off */ + list_t spa_config_list; /* previous cache file(s) */ + zio_t *spa_suspend_zio_root; /* root of all suspended I/O */ + kmutex_t spa_suspend_lock; /* protects suspend_zio_root */ + kcondvar_t spa_suspend_cv; /* notification of resume */ + uint8_t spa_suspended; /* pool is suspended */ + boolean_t spa_import_faulted; /* allow faulted vdevs */ + boolean_t spa_is_root; /* pool is root */ + int spa_minref; /* num refs when first opened */ + spa_log_state_t spa_log_state; /* log state */ /* * spa_refcnt & spa_config_lock must be the last elements * because refcount_t changes size based on compilation options. * In order for the MDB module to function correctly, the other * fields must remain in the same location. */ - spa_config_lock_t spa_config_lock; /* configuration changes */ + spa_config_lock_t spa_config_lock[SCL_LOCKS]; /* config changes */ refcount_t spa_refcount; /* number of opens */ }; -extern const char *spa_config_dir; -extern kmutex_t spa_namespace_lock; +extern const char *spa_config_path; + +#define BOOTFS_COMPRESS_VALID(compress) \ + ((compress) == ZIO_COMPRESS_LZJB || \ + ((compress) == ZIO_COMPRESS_ON && \ + ZIO_COMPRESS_ON_VALUE == ZIO_COMPRESS_LZJB) || \ + (compress) == ZIO_COMPRESS_OFF) #ifdef __cplusplus } diff --git a/zfs/lib/libzcommon/include/sys/space_map.h b/zfs/lib/libzpool/include/sys/space_map.h similarity index 99% rename from zfs/lib/libzcommon/include/sys/space_map.h rename to zfs/lib/libzpool/include/sys/space_map.h index 4f785c437..db9daef1f 100644 --- a/zfs/lib/libzcommon/include/sys/space_map.h +++ b/zfs/lib/libzpool/include/sys/space_map.h @@ -26,7 +26,7 @@ #ifndef _SYS_SPACE_MAP_H #define _SYS_SPACE_MAP_H -#pragma ident "@(#)space_map.h 1.2 06/04/02 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/txg.h b/zfs/lib/libzpool/include/sys/txg.h similarity index 94% rename from zfs/lib/libzcommon/include/sys/txg.h rename to zfs/lib/libzpool/include/sys/txg.h index d254d2278..23bdff211 100644 --- a/zfs/lib/libzcommon/include/sys/txg.h +++ b/zfs/lib/libzpool/include/sys/txg.h @@ -26,7 +26,7 @@ #ifndef _SYS_TXG_H #define _SYS_TXG_H -#pragma ident "@(#)txg.h 1.2 08/03/20 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -102,7 +102,10 @@ extern void txg_wait_open(struct dsl_pool *dp, uint64_t txg); * Returns TRUE if we are "backed up" waiting for the syncing * transaction to complete; otherwise returns FALSE. */ -extern int txg_stalled(struct dsl_pool *dp); +extern boolean_t txg_stalled(struct dsl_pool *dp); + +/* returns TRUE if someone is waiting for the next txg to sync */ +extern boolean_t txg_sync_waiting(struct dsl_pool *dp); /* * Per-txg object lists. diff --git a/zfs/lib/libzcommon/include/sys/txg_impl.h b/zfs/lib/libzpool/include/sys/txg_impl.h similarity index 96% rename from zfs/lib/libzcommon/include/sys/txg_impl.h rename to zfs/lib/libzpool/include/sys/txg_impl.h index d80062ab9..7413c662b 100644 --- a/zfs/lib/libzcommon/include/sys/txg_impl.h +++ b/zfs/lib/libzpool/include/sys/txg_impl.h @@ -26,8 +26,6 @@ #ifndef _SYS_TXG_IMPL_H #define _SYS_TXG_IMPL_H -#pragma ident "@(#)txg_impl.h 1.2 08/03/20 SMI" - #include #include @@ -66,7 +64,6 @@ typedef struct tx_state { kthread_t *tx_sync_thread; kthread_t *tx_quiesce_thread; - kthread_t *tx_timelimit_thread; } tx_state_t; #ifdef __cplusplus diff --git a/zfs/lib/libzcommon/include/sys/uberblock.h b/zfs/lib/libzpool/include/sys/uberblock.h similarity index 96% rename from zfs/lib/libzcommon/include/sys/uberblock.h rename to zfs/lib/libzpool/include/sys/uberblock.h index 4b387af1b..93d936ae4 100644 --- a/zfs/lib/libzcommon/include/sys/uberblock.h +++ b/zfs/lib/libzpool/include/sys/uberblock.h @@ -27,7 +27,7 @@ #ifndef _SYS_UBERBLOCK_H #define _SYS_UBERBLOCK_H -#pragma ident "@(#)uberblock.h 1.1 05/10/30 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/uberblock_impl.h b/zfs/lib/libzpool/include/sys/uberblock_impl.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/uberblock_impl.h rename to zfs/lib/libzpool/include/sys/uberblock_impl.h index 5f15bc846..55a0dd5ae 100644 --- a/zfs/lib/libzcommon/include/sys/uberblock_impl.h +++ b/zfs/lib/libzpool/include/sys/uberblock_impl.h @@ -26,7 +26,7 @@ #ifndef _SYS_UBERBLOCK_IMPL_H #define _SYS_UBERBLOCK_IMPL_H -#pragma ident "@(#)uberblock_impl.h 1.4 07/06/29 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/lib/libzcommon/include/sys/unique.h b/zfs/lib/libzpool/include/sys/unique.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/unique.h rename to zfs/lib/libzpool/include/sys/unique.h index d65d181a6..2ef3093ed 100644 --- a/zfs/lib/libzcommon/include/sys/unique.h +++ b/zfs/lib/libzpool/include/sys/unique.h @@ -26,7 +26,7 @@ #ifndef _SYS_UNIQUE_H #define _SYS_UNIQUE_H -#pragma ident "@(#)unique.h 1.2 07/08/02 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/lib/libzcommon/include/sys/vdev.h b/zfs/lib/libzpool/include/sys/vdev.h similarity index 84% rename from zfs/lib/libzcommon/include/sys/vdev.h rename to zfs/lib/libzpool/include/sys/vdev.h index 8435a8b66..c070d6f3d 100644 --- a/zfs/lib/libzcommon/include/sys/vdev.h +++ b/zfs/lib/libzpool/include/sys/vdev.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_VDEV_H #define _SYS_VDEV_H -#pragma ident "@(#)vdev.h 1.16 07/12/12 SMI" - #include #include #include @@ -40,13 +38,6 @@ extern "C" { extern boolean_t zfs_nocacheflush; -/* - * Fault injection modes. - */ -#define VDEV_FAULT_NONE 0 -#define VDEV_FAULT_RANDOM 1 -#define VDEV_FAULT_COUNT 2 - extern int vdev_open(vdev_t *); extern int vdev_validate(vdev_t *); extern void vdev_close(vdev_t *); @@ -54,23 +45,24 @@ extern int vdev_create(vdev_t *, uint64_t txg, boolean_t isreplace); extern void vdev_init(vdev_t *, uint64_t txg); extern void vdev_reopen(vdev_t *); extern int vdev_validate_aux(vdev_t *vd); -extern int vdev_probe(vdev_t *); +extern zio_t *vdev_probe(vdev_t *vd, zio_t *pio); +extern boolean_t vdev_is_bootable(vdev_t *vd); extern vdev_t *vdev_lookup_top(spa_t *spa, uint64_t vdev); extern vdev_t *vdev_lookup_by_guid(vdev_t *vd, uint64_t guid); extern void vdev_dtl_dirty(space_map_t *sm, uint64_t txg, uint64_t size); extern int vdev_dtl_contains(space_map_t *sm, uint64_t txg, uint64_t size); extern void vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg, int scrub_done); - -extern const char *vdev_description(vdev_t *vd); +extern boolean_t vdev_resilver_needed(vdev_t *vd, + uint64_t *minp, uint64_t *maxp); extern int vdev_metaslab_init(vdev_t *vd, uint64_t txg); extern void vdev_metaslab_fini(vdev_t *vd); extern void vdev_get_stats(vdev_t *vd, vdev_stat_t *vs); extern void vdev_clear_stats(vdev_t *vd); -extern void vdev_stat_update(zio_t *zio); +extern void vdev_stat_update(zio_t *zio, uint64_t psize); extern void vdev_scrub_stat_update(vdev_t *vd, pool_scrub_type_t type, boolean_t complete); extern int vdev_getspec(spa_t *spa, uint64_t vdev, char **vdev_spec); @@ -88,12 +80,13 @@ extern int vdev_degrade(spa_t *spa, uint64_t guid); extern int vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *); extern int vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags); -extern void vdev_clear(spa_t *spa, vdev_t *vd, boolean_t reopen_wanted); +extern void vdev_clear(spa_t *spa, vdev_t *vd); -extern int vdev_error_inject(vdev_t *vd, zio_t *zio); -extern int vdev_is_dead(vdev_t *vd); -extern int vdev_readable(vdev_t *vd); -extern int vdev_writeable(vdev_t *vd); +extern boolean_t vdev_is_dead(vdev_t *vd); +extern boolean_t vdev_readable(vdev_t *vd); +extern boolean_t vdev_writeable(vdev_t *vd); +extern boolean_t vdev_allocatable(vdev_t *vd); +extern boolean_t vdev_accessible(vdev_t *vd, zio_t *zio); extern void vdev_cache_init(vdev_t *vd); extern void vdev_cache_fini(vdev_t *vd); @@ -110,6 +103,9 @@ extern void vdev_config_dirty(vdev_t *vd); extern void vdev_config_clean(vdev_t *vd); extern int vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg); +extern void vdev_state_dirty(vdev_t *vd); +extern void vdev_state_clean(vdev_t *vd); + extern nvlist_t *vdev_config_generate(spa_t *spa, vdev_t *vd, boolean_t getstats, boolean_t isspare, boolean_t isl2cache); @@ -118,6 +114,7 @@ extern nvlist_t *vdev_config_generate(spa_t *spa, vdev_t *vd, */ struct uberblock; extern uint64_t vdev_label_offset(uint64_t psize, int l, uint64_t offset); +extern int vdev_label_number(uint64_t psise, uint64_t offset); extern nvlist_t *vdev_label_read_config(vdev_t *vd); extern void vdev_uberblock_load(zio_t *zio, vdev_t *vd, struct uberblock *ub); diff --git a/zfs/lib/libzcommon/include/sys/vdev_file.h b/zfs/lib/libzpool/include/sys/vdev_file.h similarity index 96% rename from zfs/lib/libzcommon/include/sys/vdev_file.h rename to zfs/lib/libzpool/include/sys/vdev_file.h index 580d3aefc..cd4967357 100644 --- a/zfs/lib/libzcommon/include/sys/vdev_file.h +++ b/zfs/lib/libzpool/include/sys/vdev_file.h @@ -27,7 +27,7 @@ #ifndef _SYS_VDEV_FILE_H #define _SYS_VDEV_FILE_H -#pragma ident "@(#)vdev_file.h 1.1 05/10/30 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/lib/libzcommon/include/sys/vdev_impl.h b/zfs/lib/libzpool/include/sys/vdev_impl.h similarity index 94% rename from zfs/lib/libzcommon/include/sys/vdev_impl.h rename to zfs/lib/libzpool/include/sys/vdev_impl.h index 907786793..26904d089 100644 --- a/zfs/lib/libzcommon/include/sys/vdev_impl.h +++ b/zfs/lib/libzpool/include/sys/vdev_impl.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_VDEV_IMPL_H #define _SYS_VDEV_IMPL_H -#pragma ident "@(#)vdev_impl.h 1.19 07/11/27 SMI" - #include #include #include @@ -60,16 +58,14 @@ typedef struct vdev_cache_entry vdev_cache_entry_t; */ typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *ashift); typedef void vdev_close_func_t(vdev_t *vd); -typedef int vdev_probe_func_t(vdev_t *vd); typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize); typedef int vdev_io_start_func_t(zio_t *zio); -typedef int vdev_io_done_func_t(zio_t *zio); +typedef void vdev_io_done_func_t(zio_t *zio); typedef void vdev_state_change_func_t(vdev_t *vd, int, int); typedef struct vdev_ops { vdev_open_func_t *vdev_op_open; vdev_close_func_t *vdev_op_close; - vdev_probe_func_t *vdev_op_probe; vdev_asize_func_t *vdev_op_asize; vdev_io_start_func_t *vdev_op_io_start; vdev_io_done_func_t *vdev_op_io_done; @@ -143,7 +139,9 @@ struct vdev { txg_list_t vdev_dtl_list; /* per-txg dirty DTL lists */ txg_node_t vdev_txg_node; /* per-txg dirty vdev linkage */ boolean_t vdev_remove_wanted; /* async remove wanted? */ - list_node_t vdev_dirty_node; /* config dirty list */ + boolean_t vdev_probe_wanted; /* async probe wanted? */ + list_node_t vdev_config_dirty_node; /* config dirty list */ + list_node_t vdev_state_dirty_node; /* state dirty list */ uint64_t vdev_deflate_ratio; /* deflation ratio (x512) */ uint64_t vdev_islog; /* is an intent log device */ @@ -162,22 +160,22 @@ struct vdev { char *vdev_path; /* vdev path (if any) */ char *vdev_devid; /* vdev devid (if any) */ char *vdev_physpath; /* vdev device path (if any) */ - uint64_t vdev_fault_arg; /* fault injection paramater */ - int vdev_fault_mask; /* zio types to fault */ - uint8_t vdev_fault_mode; /* fault injection mode */ + uint64_t vdev_not_present; /* not present during import */ + uint64_t vdev_unspare; /* unspare when resilvering done */ + hrtime_t vdev_last_try; /* last reopen time */ + boolean_t vdev_nowritecache; /* true if flushwritecache failed */ + boolean_t vdev_checkremove; /* temporary online test */ + boolean_t vdev_forcefault; /* force online fault */ uint8_t vdev_tmpoffline; /* device taken offline temporarily? */ uint8_t vdev_detached; /* device detached? */ + uint8_t vdev_cant_read; /* vdev is failing all reads */ + uint8_t vdev_cant_write; /* vdev is failing all writes */ uint64_t vdev_isspare; /* was a hot spare */ uint64_t vdev_isl2cache; /* was a l2cache device */ vdev_queue_t vdev_queue; /* I/O deadline schedule queue */ vdev_cache_t vdev_cache; /* physical block cache */ - uint64_t vdev_not_present; /* not present during import */ - hrtime_t vdev_last_try; /* last reopen time */ - boolean_t vdev_nowritecache; /* true if flushwritecache failed */ - uint64_t vdev_unspare; /* unspare when resilvering done */ - boolean_t vdev_checkremove; /* temporary online test */ - boolean_t vdev_forcefault; /* force online fault */ - boolean_t vdev_is_failing; /* device errors seen */ + spa_aux_vdev_t *vdev_aux; /* for l2cache vdevs */ + zio_t *vdev_probe_zio; /* root of current probe */ /* * For DTrace to work in userland (libzpool) context, these fields must @@ -188,6 +186,7 @@ struct vdev { */ kmutex_t vdev_dtl_lock; /* vdev_dtl_{map,resilver} */ kmutex_t vdev_stat_lock; /* vdev_stat */ + kmutex_t vdev_probe_lock; /* protects vdev_probe_zio */ }; #define VDEV_SKIP_SIZE (8 << 10) diff --git a/zfs/lib/libzcommon/include/sys/zap.h b/zfs/lib/libzpool/include/sys/zap.h similarity index 95% rename from zfs/lib/libzcommon/include/sys/zap.h rename to zfs/lib/libzpool/include/sys/zap.h index df1ef8c9d..f88cc068b 100644 --- a/zfs/lib/libzcommon/include/sys/zap.h +++ b/zfs/lib/libzpool/include/sys/zap.h @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ZAP_H #define _SYS_ZAP_H -#pragma ident "@(#)zap.h 1.6 07/10/25 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * ZAP - ZFS Attribute Processor @@ -243,6 +243,21 @@ int zap_count(objset_t *ds, uint64_t zapobj, uint64_t *count); int zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask, char *name); +/* + * Transfer all the entries from fromobj into intoobj. Only works on + * int_size=8 num_integers=1 values. Fails if there are any duplicated + * entries. + */ +int zap_join(objset_t *os, uint64_t fromobj, uint64_t intoobj, dmu_tx_t *tx); + +/* + * Manipulate entries where the name + value are the "same" (the name is + * a stringified version of the value). + */ +int zap_add_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx); +int zap_remove_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx); +int zap_lookup_int(objset_t *os, uint64_t obj, uint64_t value); + struct zap; struct zap_leaf; typedef struct zap_cursor { diff --git a/zfs/lib/libzcommon/include/sys/zap_impl.h b/zfs/lib/libzpool/include/sys/zap_impl.h similarity index 99% rename from zfs/lib/libzcommon/include/sys/zap_impl.h rename to zfs/lib/libzpool/include/sys/zap_impl.h index 851747198..0dc02ab6b 100644 --- a/zfs/lib/libzcommon/include/sys/zap_impl.h +++ b/zfs/lib/libzpool/include/sys/zap_impl.h @@ -26,7 +26,7 @@ #ifndef _SYS_ZAP_IMPL_H #define _SYS_ZAP_IMPL_H -#pragma ident "@(#)zap_impl.h 1.9 07/10/30 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/zap_leaf.h b/zfs/lib/libzpool/include/sys/zap_leaf.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/zap_leaf.h rename to zfs/lib/libzpool/include/sys/zap_leaf.h index c27566eec..14144e059 100644 --- a/zfs/lib/libzcommon/include/sys/zap_leaf.h +++ b/zfs/lib/libzpool/include/sys/zap_leaf.h @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ZAP_LEAF_H #define _SYS_ZAP_LEAF_H -#pragma ident "@(#)zap_leaf.h 1.5 07/11/16 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { @@ -151,7 +151,7 @@ typedef union zap_leaf_chunk { } zap_leaf_chunk_t; typedef struct zap_leaf { - krwlock_t l_rwlock; /* only used on head of chain */ + krwlock_t l_rwlock; uint64_t l_blkid; /* 1< #include @@ -181,6 +179,7 @@ typedef struct zfs_acl { #define ZFS_ACL_GROUPMASK 2 #define ZFS_ACL_PASSTHROUGH 3 #define ZFS_ACL_RESTRICTED 4 +#define ZFS_ACL_PASSTHROUGH_X 5 struct znode; struct zfsvfs; diff --git a/zfs/lib/libzcommon/include/sys/zfs_context.h b/zfs/lib/libzpool/include/sys/zfs_context.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/zfs_context.h rename to zfs/lib/libzpool/include/sys/zfs_context.h index f0133df5d..a5be3e130 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_context.h +++ b/zfs/lib/libzpool/include/sys/zfs_context.h @@ -26,7 +26,7 @@ #ifndef _SYS_ZFS_CONTEXT_H #define _SYS_ZFS_CONTEXT_H -#pragma ident "@(#)zfs_context.h 1.3 07/10/24 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { diff --git a/zfs/lib/libzcommon/include/sys/zfs_ctldir.h b/zfs/lib/libzpool/include/sys/zfs_ctldir.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/zfs_ctldir.h rename to zfs/lib/libzpool/include/sys/zfs_ctldir.h index 56e585d39..ce29625d1 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_ctldir.h +++ b/zfs/lib/libzpool/include/sys/zfs_ctldir.h @@ -26,7 +26,7 @@ #ifndef _ZFS_CTLDIR_H #define _ZFS_CTLDIR_H -#pragma ident "@(#)zfs_ctldir.h 1.4 08/02/22 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/zfs_debug.h b/zfs/lib/libzpool/include/sys/zfs_debug.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/zfs_debug.h rename to zfs/lib/libzpool/include/sys/zfs_debug.h index b9c102120..450ac1c81 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_debug.h +++ b/zfs/lib/libzpool/include/sys/zfs_debug.h @@ -26,7 +26,7 @@ #ifndef _SYS_ZFS_DEBUG_H #define _SYS_ZFS_DEBUG_H -#pragma ident "@(#)zfs_debug.h 1.3 07/02/25 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { diff --git a/zfs/lib/libzcommon/include/sys/zfs_dir.h b/zfs/lib/libzpool/include/sys/zfs_dir.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/zfs_dir.h rename to zfs/lib/libzpool/include/sys/zfs_dir.h index 2d043654e..ebb66e8ae 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_dir.h +++ b/zfs/lib/libzpool/include/sys/zfs_dir.h @@ -26,7 +26,7 @@ #ifndef _SYS_FS_ZFS_DIR_H #define _SYS_FS_ZFS_DIR_H -#pragma ident "@(#)zfs_dir.h 1.5 07/11/09 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/zfs_fuid.h b/zfs/lib/libzpool/include/sys/zfs_fuid.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/zfs_fuid.h rename to zfs/lib/libzpool/include/sys/zfs_fuid.h index 29bc29ebe..810ffc81a 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_fuid.h +++ b/zfs/lib/libzpool/include/sys/zfs_fuid.h @@ -26,7 +26,7 @@ #ifndef _SYS_FS_ZFS_FUID_H #define _SYS_FS_ZFS_FUID_H -#pragma ident "@(#)zfs_fuid.h 1.4 08/01/31 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef _KERNEL #include diff --git a/zfs/lib/libzcommon/include/sys/zfs_ioctl.h b/zfs/lib/libzpool/include/sys/zfs_ioctl.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/zfs_ioctl.h rename to zfs/lib/libzpool/include/sys/zfs_ioctl.h index dbad77cc6..1692608bb 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_ioctl.h +++ b/zfs/lib/libzpool/include/sys/zfs_ioctl.h @@ -26,7 +26,7 @@ #ifndef _SYS_ZFS_IOCTL_H #define _SYS_ZFS_IOCTL_H -#pragma ident "@(#)zfs_ioctl.h 1.19 08/04/27 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/zfs_rlock.h b/zfs/lib/libzpool/include/sys/zfs_rlock.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/zfs_rlock.h rename to zfs/lib/libzpool/include/sys/zfs_rlock.h index 0640e451d..f302b663e 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_rlock.h +++ b/zfs/lib/libzpool/include/sys/zfs_rlock.h @@ -26,7 +26,7 @@ #ifndef _SYS_FS_ZFS_RLOCK_H #define _SYS_FS_ZFS_RLOCK_H -#pragma ident "@(#)zfs_rlock.h 1.2 06/06/19 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { diff --git a/zfs/lib/libzcommon/include/sys/zfs_vfsops.h b/zfs/lib/libzpool/include/sys/zfs_vfsops.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/zfs_vfsops.h rename to zfs/lib/libzpool/include/sys/zfs_vfsops.h index a3c2251ba..87b75e6e7 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_vfsops.h +++ b/zfs/lib/libzpool/include/sys/zfs_vfsops.h @@ -26,7 +26,7 @@ #ifndef _SYS_FS_ZFS_VFSOPS_H #define _SYS_FS_ZFS_VFSOPS_H -#pragma ident "@(#)zfs_vfsops.h 1.11 08/02/22 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/zfs_znode.h b/zfs/lib/libzpool/include/sys/zfs_znode.h similarity index 95% rename from zfs/lib/libzcommon/include/sys/zfs_znode.h rename to zfs/lib/libzpool/include/sys/zfs_znode.h index 0cb2dd618..a5416525c 100644 --- a/zfs/lib/libzcommon/include/sys/zfs_znode.h +++ b/zfs/lib/libzpool/include/sys/zfs_znode.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_FS_ZFS_ZNODE_H #define _SYS_FS_ZFS_ZNODE_H -#pragma ident "@(#)zfs_znode.h 1.25 07/12/07 SMI" - #ifdef _KERNEL #include #include @@ -257,19 +255,21 @@ typedef struct znode { * Macros for dealing with dmu_buf_hold */ #define ZFS_OBJ_HASH(obj_num) ((obj_num) & (ZFS_OBJ_MTX_SZ - 1)) -#define ZFS_OBJ_MUTEX(zp) \ - (&(zp)->z_zfsvfs->z_hold_mtx[ZFS_OBJ_HASH((zp)->z_id)]) +#define ZFS_OBJ_MUTEX(zfsvfs, obj_num) \ + (&(zfsvfs)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)]) #define ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num) \ - mutex_enter(&(zfsvfs)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)]); + mutex_enter(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) +#define ZFS_OBJ_HOLD_TRYENTER(zfsvfs, obj_num) \ + mutex_tryenter(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) #define ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num) \ - mutex_exit(&(zfsvfs)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)]) + mutex_exit(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) /* * Macros to encode/decode ZFS stored time values from/to struct timespec */ #define ZFS_TIME_ENCODE(tp, stmp) \ { \ - (stmp)[0] = (uint64_t)(tp)->tv_sec; \ + (stmp)[0] = (uint64_t)(tp)->tv_sec; \ (stmp)[1] = (uint64_t)(tp)->tv_nsec; \ } @@ -290,7 +290,7 @@ typedef struct znode { if ((zfsvfs)->z_atime && !((zfsvfs)->z_vfs->vfs_flag & VFS_RDONLY)) \ zfs_time_stamper(zp, ACCESSED, NULL) -extern int zfs_init_fs(zfsvfs_t *, znode_t **, cred_t *); +extern int zfs_init_fs(zfsvfs_t *, znode_t **); extern void zfs_set_dataprop(objset_t *); extern void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *, dmu_tx_t *tx); @@ -338,6 +338,9 @@ extern void zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, extern void zfs_xvattr_set(znode_t *zp, xvattr_t *xvap); extern void zfs_upgrade(zfsvfs_t *zfsvfs, dmu_tx_t *tx); +extern caddr_t zfs_map_page(page_t *, enum seg_rw); +extern void zfs_unmap_page(page_t *, caddr_t); + extern zil_get_data_t zfs_get_data; extern zil_replay_func_t *zfs_replay_vector[TX_MAX_TYPE]; extern int zfsfstype; diff --git a/zfs/lib/libzcommon/include/sys/zil.h b/zfs/lib/libzpool/include/sys/zil.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/zil.h rename to zfs/lib/libzpool/include/sys/zil.h index d7b129b4c..4d02d14f7 100644 --- a/zfs/lib/libzcommon/include/sys/zil.h +++ b/zfs/lib/libzpool/include/sys/zil.h @@ -26,8 +26,6 @@ #ifndef _SYS_ZIL_H #define _SYS_ZIL_H -#pragma ident "@(#)zil.h 1.15 08/02/22 SMI" - #include #include #include @@ -337,6 +335,7 @@ typedef void zil_parse_blk_func_t(zilog_t *zilog, blkptr_t *bp, void *arg, typedef void zil_parse_lr_func_t(zilog_t *zilog, lr_t *lr, void *arg, uint64_t txg); typedef int zil_replay_func_t(); +typedef void zil_replay_cleaner_t(); typedef int zil_get_data_t(void *arg, lr_write_t *lr, char *dbuf, zio_t *zio); extern uint64_t zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func, @@ -352,7 +351,8 @@ extern zilog_t *zil_open(objset_t *os, zil_get_data_t *get_data); extern void zil_close(zilog_t *zilog); extern void zil_replay(objset_t *os, void *arg, uint64_t *txgp, - zil_replay_func_t *replay_func[TX_MAX_TYPE]); + zil_replay_func_t *replay_func[TX_MAX_TYPE], + zil_replay_cleaner_t *replay_cleaner); extern void zil_destroy(zilog_t *zilog, boolean_t keep_first); extern void zil_rollback_destroy(zilog_t *zilog, dmu_tx_t *tx); @@ -362,6 +362,8 @@ extern uint64_t zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx); extern void zil_commit(zilog_t *zilog, uint64_t seq, uint64_t oid); extern int zil_claim(char *osname, void *txarg); +extern int zil_check_log_chain(char *osname, void *txarg); +extern int zil_clear_log_chain(char *osname, void *txarg); extern void zil_sync(zilog_t *zilog, dmu_tx_t *tx); extern void zil_clean(zilog_t *zilog); extern int zil_is_committed(zilog_t *zilog); diff --git a/zfs/lib/libzcommon/include/sys/zil_impl.h b/zfs/lib/libzpool/include/sys/zil_impl.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/zil_impl.h rename to zfs/lib/libzpool/include/sys/zil_impl.h index 4f51cc904..0fc800b96 100644 --- a/zfs/lib/libzcommon/include/sys/zil_impl.h +++ b/zfs/lib/libzpool/include/sys/zil_impl.h @@ -26,7 +26,7 @@ #ifndef _SYS_ZIL_IMPL_H #define _SYS_ZIL_IMPL_H -#pragma ident "@(#)zil_impl.h 1.7 07/12/12 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzcommon/include/sys/zio.h b/zfs/lib/libzpool/include/sys/zio.h similarity index 72% rename from zfs/lib/libzcommon/include/sys/zio.h rename to zfs/lib/libzpool/include/sys/zio.h index b25a845a7..4de78dfee 100644 --- a/zfs/lib/libzcommon/include/sys/zio.h +++ b/zfs/lib/libzpool/include/sys/zio.h @@ -27,13 +27,10 @@ #ifndef _ZIO_H #define _ZIO_H -#pragma ident "@(#)zio.h 1.20 08/04/01 SMI" - #include #include #include #include -#include #include #include @@ -60,10 +57,6 @@ typedef struct zio_block_tail { (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\ sizeof (uint64_t)) -#define ZIO_GET_IOSIZE(zio) \ - (BP_IS_GANG((zio)->io_bp) ? \ - SPA_GANGBLOCKSIZE : BP_GET_PSIZE((zio)->io_bp)) - typedef struct zio_gbh { blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS]; uint64_t zg_filler[SPA_GBH_FILLER]; @@ -125,58 +118,64 @@ enum zio_compress { #define ZIO_FLAG_MUSTSUCCEED 0x00000 #define ZIO_FLAG_CANFAIL 0x00001 -#define ZIO_FLAG_FAILFAST 0x00002 -#define ZIO_FLAG_CONFIG_HELD 0x00004 -#define ZIO_FLAG_CONFIG_GRABBED 0x00008 +#define ZIO_FLAG_SPECULATIVE 0x00002 +#define ZIO_FLAG_CONFIG_WRITER 0x00004 +#define ZIO_FLAG_DONT_RETRY 0x00008 #define ZIO_FLAG_DONT_CACHE 0x00010 #define ZIO_FLAG_DONT_QUEUE 0x00020 -#define ZIO_FLAG_DONT_PROPAGATE 0x00040 -#define ZIO_FLAG_DONT_RETRY 0x00080 +#define ZIO_FLAG_DONT_AGGREGATE 0x00040 +#define ZIO_FLAG_DONT_PROPAGATE 0x00080 -#define ZIO_FLAG_PHYSICAL 0x00100 -#define ZIO_FLAG_IO_BYPASS 0x00200 -#define ZIO_FLAG_IO_REPAIR 0x00400 -#define ZIO_FLAG_SPECULATIVE 0x00800 +#define ZIO_FLAG_IO_BYPASS 0x00100 +#define ZIO_FLAG_IO_REPAIR 0x00200 +#define ZIO_FLAG_IO_RETRY 0x00400 +#define ZIO_FLAG_IO_REWRITE 0x00800 -#define ZIO_FLAG_RESILVER 0x01000 -#define ZIO_FLAG_SCRUB 0x02000 -#define ZIO_FLAG_SCRUB_THREAD 0x04000 -#define ZIO_FLAG_SUBBLOCK 0x08000 +#define ZIO_FLAG_PROBE 0x01000 +#define ZIO_FLAG_RESILVER 0x02000 +#define ZIO_FLAG_SCRUB 0x04000 +#define ZIO_FLAG_SCRUB_THREAD 0x08000 -#define ZIO_FLAG_NOBOOKMARK 0x10000 -#define ZIO_FLAG_USER 0x20000 -#define ZIO_FLAG_METADATA 0x40000 -#define ZIO_FLAG_WRITE_RETRY 0x80000 +#define ZIO_FLAG_GANG_CHILD 0x10000 #define ZIO_FLAG_GANG_INHERIT \ (ZIO_FLAG_CANFAIL | \ - ZIO_FLAG_FAILFAST | \ - ZIO_FLAG_CONFIG_HELD | \ - ZIO_FLAG_DONT_CACHE | \ - ZIO_FLAG_DONT_RETRY | \ - ZIO_FLAG_IO_REPAIR | \ ZIO_FLAG_SPECULATIVE | \ + ZIO_FLAG_CONFIG_WRITER | \ + ZIO_FLAG_DONT_RETRY | \ + ZIO_FLAG_DONT_CACHE | \ + ZIO_FLAG_DONT_AGGREGATE | \ ZIO_FLAG_RESILVER | \ ZIO_FLAG_SCRUB | \ - ZIO_FLAG_SCRUB_THREAD | \ - ZIO_FLAG_USER | \ - ZIO_FLAG_METADATA) + ZIO_FLAG_SCRUB_THREAD) #define ZIO_FLAG_VDEV_INHERIT \ (ZIO_FLAG_GANG_INHERIT | \ - ZIO_FLAG_PHYSICAL) - -#define ZIO_FLAG_RETRY_INHERIT \ - (ZIO_FLAG_VDEV_INHERIT | \ - ZIO_FLAG_CONFIG_GRABBED | \ - ZIO_FLAG_DONT_PROPAGATE | \ - ZIO_FLAG_NOBOOKMARK) - + ZIO_FLAG_IO_REPAIR | \ + ZIO_FLAG_IO_RETRY | \ + ZIO_FLAG_PROBE) #define ZIO_PIPELINE_CONTINUE 0x100 #define ZIO_PIPELINE_STOP 0x101 +#define ZIO_GANG_CHILD_FLAGS(zio) \ + (((zio)->io_flags & ZIO_FLAG_GANG_INHERIT) | \ + ZIO_FLAG_GANG_CHILD | ZIO_FLAG_CANFAIL) + +enum zio_child { + ZIO_CHILD_VDEV = 0, + ZIO_CHILD_GANG, + ZIO_CHILD_LOGICAL, + ZIO_CHILD_TYPES +}; + +enum zio_wait_type { + ZIO_WAIT_READY = 0, + ZIO_WAIT_DONE, + ZIO_WAIT_TYPES +}; + /* * We'll take the unused errnos, 'EBADE' and 'EBADR' (from the Convergent * graveyard) to indicate checksum errors and fragmentation. @@ -217,24 +216,64 @@ typedef struct zbookmark { uint64_t zb_blkid; } zbookmark_t; +typedef struct zio_prop { + enum zio_checksum zp_checksum; + enum zio_compress zp_compress; + dmu_object_type_t zp_type; + uint8_t zp_level; + uint8_t zp_ndvas; +} zio_prop_t; + +typedef struct zio_gang_node { + zio_gbh_phys_t *gn_gbh; + struct zio_gang_node *gn_child[SPA_GBH_NBLKPTRS]; +} zio_gang_node_t; + +typedef zio_t *zio_gang_issue_func_t(zio_t *zio, blkptr_t *bp, + zio_gang_node_t *gn, void *data); + +typedef void zio_transform_func_t(zio_t *zio, void *data, uint64_t size); + +typedef struct zio_transform { + void *zt_orig_data; + uint64_t zt_orig_size; + uint64_t zt_bufsize; + zio_transform_func_t *zt_transform; + struct zio_transform *zt_next; +} zio_transform_t; + +typedef int zio_pipe_stage_t(zio_t *zio); + +/* + * The io_reexecute flags are distinct from io_flags because the child must + * be able to propagate them to the parent. The normal io_flags are local + * to the zio, not protected by any lock, and not modifiable by children; + * the reexecute flags are protected by io_lock, modifiable by children, + * and always propagated -- even when ZIO_FLAG_DONT_PROPAGATE is set. + */ +#define ZIO_REEXECUTE_NOW 0x01 +#define ZIO_REEXECUTE_SUSPEND 0x02 + struct zio { /* Core information about this I/O */ - zio_t *io_parent; - zio_t *io_root; - spa_t *io_spa; zbookmark_t io_bookmark; - enum zio_checksum io_checksum; - enum zio_compress io_compress; - int io_ndvas; + zio_prop_t io_prop; + zio_type_t io_type; + enum zio_child io_child_type; + int io_cmd; + uint8_t io_priority; + uint8_t io_reexecute; + uint8_t io_async_root; uint64_t io_txg; + spa_t *io_spa; blkptr_t *io_bp; blkptr_t io_bp_copy; + zio_t *io_parent; zio_t *io_child; zio_t *io_sibling_prev; zio_t *io_sibling_next; - zio_transform_t *io_transform_stack; zio_t *io_logical; - list_node_t zio_link_node; + zio_transform_t *io_transform_stack; /* Callback info */ zio_done_func_t *io_ready; @@ -249,9 +288,9 @@ struct zio { /* Stuff for the vdev stack */ vdev_t *io_vd; void *io_vsd; + zio_done_func_t *io_vsd_free; uint64_t io_offset; uint64_t io_deadline; - uint64_t io_timestamp; avl_node_t io_offset_node; avl_node_t io_deadline_node; avl_tree_t *io_vdev_tree; @@ -260,21 +299,17 @@ struct zio { /* Internal pipeline state */ int io_flags; - int io_orig_flags; - enum zio_type io_type; - enum zio_stage io_stage; - enum zio_stage io_orig_stage; - uint8_t io_stalled; - uint8_t io_priority; - struct dk_callback io_dk_callback; - int io_cmd; - int io_retries; - int io_error; - uint32_t io_numerrors; + zio_stage_t io_stage; uint32_t io_pipeline; + int io_orig_flags; + zio_stage_t io_orig_stage; uint32_t io_orig_pipeline; - uint64_t io_children_notready; - uint64_t io_children_notdone; + int io_error; + int io_child_error[ZIO_CHILD_TYPES]; + uint64_t io_children[ZIO_CHILD_TYPES][ZIO_WAIT_TYPES]; + uint64_t *io_stall; + zio_gang_node_t *io_gang_tree; + void *io_executor; void *io_waiter; kmutex_t io_lock; kcondvar_t io_cv; @@ -289,25 +324,26 @@ extern zio_t *zio_null(zio_t *pio, spa_t *spa, extern zio_t *zio_root(spa_t *spa, zio_done_func_t *done, void *private, int flags); -extern zio_t *zio_read(zio_t *pio, spa_t *spa, blkptr_t *bp, void *data, +extern zio_t *zio_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, void *data, uint64_t size, zio_done_func_t *done, void *private, + int priority, int flags, const zbookmark_t *zb); + +extern zio_t *zio_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, + void *data, uint64_t size, zio_prop_t *zp, + zio_done_func_t *ready, zio_done_func_t *done, void *private, + int priority, int flags, const zbookmark_t *zb); + +extern zio_t *zio_rewrite(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, + void *data, uint64_t size, zio_done_func_t *done, void *private, int priority, int flags, zbookmark_t *zb); -extern zio_t *zio_write(zio_t *pio, spa_t *spa, int checksum, int compress, - int ncopies, uint64_t txg, blkptr_t *bp, void *data, uint64_t size, - zio_done_func_t *ready, zio_done_func_t *done, void *private, int priority, - int flags, zbookmark_t *zb); - -extern zio_t *zio_rewrite(zio_t *pio, spa_t *spa, int checksum, - uint64_t txg, blkptr_t *bp, void *data, uint64_t size, - zio_done_func_t *done, void *private, int priority, int flags, - zbookmark_t *zb); +extern void zio_skip_write(zio_t *zio); extern zio_t *zio_free(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, - zio_done_func_t *done, void *private); + zio_done_func_t *done, void *private, int flags); extern zio_t *zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, - zio_done_func_t *done, void *private); + zio_done_func_t *done, void *private, int flags); extern zio_t *zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd, zio_done_func_t *done, void *private, int priority, int flags); @@ -332,9 +368,6 @@ extern void zio_nowait(zio_t *zio); extern void zio_execute(zio_t *zio); extern void zio_interrupt(zio_t *zio); -extern int zio_wait_for_children_ready(zio_t *zio); -extern int zio_wait_for_children_done(zio_t *zio); - extern void *zio_buf_alloc(size_t size); extern void zio_buf_free(void *buf, size_t size); extern void *zio_data_buf_alloc(size_t size); @@ -342,25 +375,27 @@ extern void zio_data_buf_free(void *buf, size_t size); extern void zio_resubmit_stage_async(void *); -/* - * Delegate I/O to a child vdev. - */ extern zio_t *zio_vdev_child_io(zio_t *zio, blkptr_t *bp, vdev_t *vd, uint64_t offset, void *data, uint64_t size, int type, int priority, int flags, zio_done_func_t *done, void *private); +extern zio_t *zio_vdev_delegated_io(vdev_t *vd, uint64_t offset, + void *data, uint64_t size, int type, int priority, + int flags, zio_done_func_t *done, void *private); + extern void zio_vdev_io_bypass(zio_t *zio); extern void zio_vdev_io_reissue(zio_t *zio); extern void zio_vdev_io_redone(zio_t *zio); extern void zio_checksum_verified(zio_t *zio); -extern void zio_set_gang_verifier(zio_t *zio, zio_cksum_t *zcp); +extern int zio_worst_error(int e1, int e2); extern uint8_t zio_checksum_select(uint8_t child, uint8_t parent); extern uint8_t zio_compress_select(uint8_t child, uint8_t parent); -extern boolean_t zio_should_retry(zio_t *zio); -extern int zio_vdev_resume_io(spa_t *); +extern void zio_suspend(spa_t *spa, zio_t *zio); +extern void zio_resume(spa_t *spa); +extern void zio_resume_wait(spa_t *spa); /* * Initial setup and teardown. @@ -380,6 +415,7 @@ extern int zio_inject_list_next(int *id, char *name, size_t buflen, extern int zio_clear_fault(int id); extern int zio_handle_fault_injection(zio_t *zio, int error); extern int zio_handle_device_injection(vdev_t *vd, int error); +extern int zio_handle_label_injection(zio_t *zio, int error); #ifdef __cplusplus } diff --git a/zfs/lib/libzcommon/include/sys/zio_checksum.h b/zfs/lib/libzpool/include/sys/zio_checksum.h similarity index 91% rename from zfs/lib/libzcommon/include/sys/zio_checksum.h rename to zfs/lib/libzpool/include/sys/zio_checksum.h index 77e1d8044..da407399d 100644 --- a/zfs/lib/libzcommon/include/sys/zio_checksum.h +++ b/zfs/lib/libzpool/include/sys/zio_checksum.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ZIO_CHECKSUM_H #define _SYS_ZIO_CHECKSUM_H -#pragma ident "@(#)zio_checksum.h 1.2 06/03/03 SMI" - #include #ifdef __cplusplus @@ -64,7 +62,7 @@ extern zio_checksum_t fletcher_4_incremental_byteswap; extern zio_checksum_t zio_checksum_SHA256; -extern void zio_checksum(uint_t checksum, zio_cksum_t *zcp, +extern void zio_checksum_compute(zio_t *zio, enum zio_checksum checksum, void *data, uint64_t size); extern int zio_checksum_error(zio_t *zio); diff --git a/zfs/lib/libzcommon/include/sys/zio_compress.h b/zfs/lib/libzpool/include/sys/zio_compress.h similarity index 97% rename from zfs/lib/libzcommon/include/sys/zio_compress.h rename to zfs/lib/libzpool/include/sys/zio_compress.h index 03b20d629..66ee8d45b 100644 --- a/zfs/lib/libzcommon/include/sys/zio_compress.h +++ b/zfs/lib/libzpool/include/sys/zio_compress.h @@ -27,7 +27,7 @@ #ifndef _SYS_ZIO_COMPRESS_H #define _SYS_ZIO_COMPRESS_H -#pragma ident "@(#)zio_compress.h 1.2 07/03/22 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/lib/libzcommon/include/sys/zio_impl.h b/zfs/lib/libzpool/include/sys/zio_impl.h similarity index 54% rename from zfs/lib/libzcommon/include/sys/zio_impl.h rename to zfs/lib/libzpool/include/sys/zio_impl.h index 80cbaaa25..e7503b733 100644 --- a/zfs/lib/libzcommon/include/sys/zio_impl.h +++ b/zfs/lib/libzpool/include/sys/zio_impl.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _ZIO_IMPL_H #define _ZIO_IMPL_H -#pragma ident "@(#)zio_impl.h 1.6 07/12/12 SMI" - #include #include @@ -40,63 +38,60 @@ extern "C" { */ typedef enum zio_stage { ZIO_STAGE_OPEN = 0, /* RWFCI */ - ZIO_STAGE_WAIT_FOR_CHILDREN_READY, /* RWFCI */ - ZIO_STAGE_READ_INIT, /* R---- */ ZIO_STAGE_ISSUE_ASYNC, /* -W--- */ - ZIO_STAGE_WRITE_COMPRESS, /* -W--- */ + + ZIO_STAGE_READ_BP_INIT, /* R---- */ + ZIO_STAGE_WRITE_BP_INIT, /* -W--- */ + ZIO_STAGE_CHECKSUM_GENERATE, /* -W--- */ - ZIO_STAGE_GET_GANG_HEADER, /* -WFC- */ - ZIO_STAGE_REWRITE_GANG_MEMBERS, /* -W--- */ - ZIO_STAGE_FREE_GANG_MEMBERS, /* --F-- */ - ZIO_STAGE_CLAIM_GANG_MEMBERS, /* ---C- */ + ZIO_STAGE_GANG_ASSEMBLE, /* RWFC- */ + ZIO_STAGE_GANG_ISSUE, /* RWFC- */ ZIO_STAGE_DVA_ALLOCATE, /* -W--- */ ZIO_STAGE_DVA_FREE, /* --F-- */ ZIO_STAGE_DVA_CLAIM, /* ---C- */ - ZIO_STAGE_GANG_CHECKSUM_GENERATE, /* -W--- */ - ZIO_STAGE_READY, /* RWFCI */ ZIO_STAGE_VDEV_IO_START, /* RW--I */ ZIO_STAGE_VDEV_IO_DONE, /* RW--I */ ZIO_STAGE_VDEV_IO_ASSESS, /* RW--I */ - ZIO_STAGE_WAIT_FOR_CHILDREN_DONE, /* RWFCI */ - ZIO_STAGE_CHECKSUM_VERIFY, /* R---- */ - ZIO_STAGE_READ_GANG_MEMBERS, /* R---- */ - ZIO_STAGE_READ_DECOMPRESS, /* R---- */ - ZIO_STAGE_ASSESS, /* RWFCI */ - ZIO_STAGE_DONE /* RWFCI */ + ZIO_STAGE_DONE, /* RWFCI */ + ZIO_STAGES } zio_stage_t; #define ZIO_INTERLOCK_STAGES \ - ((1U << ZIO_STAGE_WAIT_FOR_CHILDREN_READY) | \ - (1U << ZIO_STAGE_READY) | \ - (1U << ZIO_STAGE_WAIT_FOR_CHILDREN_DONE) | \ - (1U << ZIO_STAGE_ASSESS) | \ + ((1U << ZIO_STAGE_READY) | \ (1U << ZIO_STAGE_DONE)) +#define ZIO_INTERLOCK_PIPELINE \ + ZIO_INTERLOCK_STAGES + #define ZIO_VDEV_IO_STAGES \ ((1U << ZIO_STAGE_VDEV_IO_START) | \ (1U << ZIO_STAGE_VDEV_IO_DONE) | \ (1U << ZIO_STAGE_VDEV_IO_ASSESS)) -#define ZIO_READ_PHYS_PIPELINE \ +#define ZIO_VDEV_CHILD_PIPELINE \ + (ZIO_VDEV_IO_STAGES | \ + (1U << ZIO_STAGE_DONE)) + +#define ZIO_READ_COMMON_STAGES \ (ZIO_INTERLOCK_STAGES | \ ZIO_VDEV_IO_STAGES | \ (1U << ZIO_STAGE_CHECKSUM_VERIFY)) -#define ZIO_READ_GANG_PIPELINE \ - ZIO_READ_PHYS_PIPELINE +#define ZIO_READ_PHYS_PIPELINE \ + ZIO_READ_COMMON_STAGES #define ZIO_READ_PIPELINE \ - (1U << ZIO_STAGE_READ_INIT) | \ - ZIO_READ_PHYS_PIPELINE + (ZIO_READ_COMMON_STAGES | \ + (1U << ZIO_STAGE_READ_BP_INIT)) #define ZIO_WRITE_COMMON_STAGES \ (ZIO_INTERLOCK_STAGES | \ @@ -107,66 +102,36 @@ typedef enum zio_stage { #define ZIO_WRITE_PHYS_PIPELINE \ ZIO_WRITE_COMMON_STAGES +#define ZIO_REWRITE_PIPELINE \ + (ZIO_WRITE_COMMON_STAGES | \ + (1U << ZIO_STAGE_WRITE_BP_INIT)) + #define ZIO_WRITE_PIPELINE \ (ZIO_WRITE_COMMON_STAGES | \ - (1U << ZIO_STAGE_WRITE_COMPRESS) | \ + (1U << ZIO_STAGE_WRITE_BP_INIT) | \ (1U << ZIO_STAGE_DVA_ALLOCATE)) -#define ZIO_GANG_REWRITE_STAGES \ - ((1U << ZIO_STAGE_GET_GANG_HEADER) | \ - (1U << ZIO_STAGE_REWRITE_GANG_MEMBERS) | \ - (1U << ZIO_STAGE_GANG_CHECKSUM_GENERATE)) +#define ZIO_GANG_STAGES \ + ((1U << ZIO_STAGE_GANG_ASSEMBLE) | \ + (1U << ZIO_STAGE_GANG_ISSUE)) -#define ZIO_GANG_FREE_STAGES \ - ((1U << ZIO_STAGE_GET_GANG_HEADER) | \ - (1U << ZIO_STAGE_FREE_GANG_MEMBERS)) - -#define ZIO_GANG_CLAIM_STAGES \ - ((1U << ZIO_STAGE_GET_GANG_HEADER) | \ - (1U << ZIO_STAGE_CLAIM_GANG_MEMBERS)) - -#define ZIO_REWRITE_PIPELINE(bp) \ - (ZIO_WRITE_COMMON_STAGES | \ - (BP_IS_GANG(bp) ? ZIO_GANG_REWRITE_STAGES : 0)) - -#define ZIO_WRITE_ALLOCATE_PIPELINE \ - (ZIO_WRITE_COMMON_STAGES | \ - (1U << ZIO_STAGE_DVA_ALLOCATE)) - -#define ZIO_FREE_PIPELINE(bp) \ +#define ZIO_FREE_PIPELINE \ (ZIO_INTERLOCK_STAGES | \ - (1U << ZIO_STAGE_DVA_FREE) | \ - (BP_IS_GANG(bp) ? ZIO_GANG_FREE_STAGES : 0)) + (1U << ZIO_STAGE_DVA_FREE)) -#define ZIO_CLAIM_PIPELINE(bp) \ +#define ZIO_CLAIM_PIPELINE \ (ZIO_INTERLOCK_STAGES | \ - (1U << ZIO_STAGE_DVA_CLAIM) | \ - (BP_IS_GANG(bp) ? ZIO_GANG_CLAIM_STAGES : 0)) + (1U << ZIO_STAGE_DVA_CLAIM)) #define ZIO_IOCTL_PIPELINE \ (ZIO_INTERLOCK_STAGES | \ - ZIO_VDEV_IO_STAGES) + (1U << ZIO_STAGE_VDEV_IO_START) | \ + (1U << ZIO_STAGE_VDEV_IO_ASSESS)) - -#define ZIO_WAIT_FOR_CHILDREN_PIPELINE \ - ZIO_INTERLOCK_STAGES - -#define ZIO_VDEV_CHILD_PIPELINE \ - (ZIO_VDEV_IO_STAGES | \ - (1U << ZIO_STAGE_ASSESS) | \ - (1U << ZIO_STAGE_WAIT_FOR_CHILDREN_DONE) | \ - (1U << ZIO_STAGE_DONE)) - -#define ZIO_ERROR_PIPELINE_MASK \ - ZIO_INTERLOCK_STAGES - -typedef struct zio_transform zio_transform_t; -struct zio_transform { - void *zt_data; - uint64_t zt_size; - uint64_t zt_bufsize; - zio_transform_t *zt_next; -}; +#define ZIO_CONFIG_LOCK_BLOCKING_STAGES \ + ((1U << ZIO_STAGE_VDEV_IO_START) | \ + (1U << ZIO_STAGE_DVA_ALLOCATE) | \ + (1U << ZIO_STAGE_DVA_CLAIM)) extern void zio_inject_init(void); extern void zio_inject_fini(void); diff --git a/zfs/lib/libzcommon/include/sys/zvol.h b/zfs/lib/libzpool/include/sys/zvol.h similarity index 98% rename from zfs/lib/libzcommon/include/sys/zvol.h rename to zfs/lib/libzpool/include/sys/zvol.h index 0b4a8777b..06adc667e 100644 --- a/zfs/lib/libzcommon/include/sys/zvol.h +++ b/zfs/lib/libzpool/include/sys/zvol.h @@ -27,7 +27,7 @@ #ifndef _SYS_ZVOL_H #define _SYS_ZVOL_H -#pragma ident "@(#)zvol.h 1.5 08/04/01 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/lib/libzpool/lzjb.c b/zfs/lib/libzpool/lzjb.c index 22f9c2b1b..7fcde8475 100644 --- a/zfs/lib/libzpool/lzjb.c +++ b/zfs/lib/libzpool/lzjb.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)lzjb.c 1.3 07/03/22 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * We keep our own copy of this algorithm for 2 main reasons: diff --git a/zfs/lib/libzpool/metaslab.c b/zfs/lib/libzpool/metaslab.c index 00533efa8..87727fac2 100644 --- a/zfs/lib/libzpool/metaslab.c +++ b/zfs/lib/libzpool/metaslab.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)metaslab.c 1.17 07/11/27 SMI" - #include #include #include @@ -716,7 +714,7 @@ metaslab_group_alloc(metaslab_group_t *mg, uint64_t size, uint64_t txg, */ static int metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize, - dva_t *dva, int d, dva_t *hintdva, uint64_t txg, boolean_t hintdva_avoid) + dva_t *dva, int d, dva_t *hintdva, uint64_t txg, int flags) { metaslab_group_t *mg, *rotor; vdev_t *vd; @@ -758,7 +756,7 @@ metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize, */ if (hintdva) { vd = vdev_lookup_top(spa, DVA_GET_VDEV(&hintdva[d])); - if (hintdva_avoid) + if (flags & METASLAB_HINTBP_AVOID) mg = vd->vdev_mg->mg_next; else mg = vd->vdev_mg; @@ -781,9 +779,9 @@ top: do { vd = mg->mg_vd; /* - * Dont allocate from faulted devices + * Don't allocate from faulted devices. */ - if (!vdev_writeable(vd)) + if (!vdev_allocatable(vd)) goto next; /* * Avoid writing single-copy data to a failing vdev @@ -844,7 +842,7 @@ top: DVA_SET_VDEV(&dva[d], vd->vdev_id); DVA_SET_OFFSET(&dva[d], offset); - DVA_SET_GANG(&dva[d], 0); + DVA_SET_GANG(&dva[d], !!(flags & METASLAB_GANG_HEADER)); DVA_SET_ASIZE(&dva[d], asize); return (0); @@ -906,38 +904,6 @@ metaslab_free_dva(spa_t *spa, const dva_t *dva, uint64_t txg, boolean_t now) if (msp->ms_freemap[txg & TXG_MASK].sm_space == 0) vdev_dirty(vd, VDD_METASLAB, msp, txg); space_map_add(&msp->ms_freemap[txg & TXG_MASK], offset, size); - - /* - * verify that this region is actually allocated in - * either a ms_allocmap or the ms_map - */ - if (msp->ms_map.sm_loaded) { - boolean_t allocd = B_FALSE; - int i; - - if (!space_map_contains(&msp->ms_map, offset, size)) { - allocd = B_TRUE; - } else { - for (i = 0; i < TXG_CONCURRENT_STATES; i++) { - space_map_t *sm = &msp->ms_allocmap - [(txg - i) & TXG_MASK]; - if (space_map_contains(sm, - offset, size)) { - allocd = B_TRUE; - break; - } - } - } - - if (!allocd) { - zfs_panic_recover("freeing free segment " - "(vdev=%llu offset=%llx size=%llx)", - (longlong_t)vdev, (longlong_t)offset, - (longlong_t)size); - } - } - - } mutex_exit(&msp->ms_lock); @@ -973,16 +939,18 @@ metaslab_claim_dva(spa_t *spa, const dva_t *dva, uint64_t txg) mutex_enter(&msp->ms_lock); error = metaslab_activate(msp, METASLAB_WEIGHT_SECONDARY); - if (error) { + if (error || txg == 0) { /* txg == 0 indicates dry run */ mutex_exit(&msp->ms_lock); return (error); } - if (msp->ms_allocmap[txg & TXG_MASK].sm_space == 0) - vdev_dirty(vd, VDD_METASLAB, msp, txg); - space_map_claim(&msp->ms_map, offset, size); - space_map_add(&msp->ms_allocmap[txg & TXG_MASK], offset, size); + + if (spa_mode & FWRITE) { /* don't dirty if we're zdb(1M) */ + if (msp->ms_allocmap[txg & TXG_MASK].sm_space == 0) + vdev_dirty(vd, VDD_METASLAB, msp, txg); + space_map_add(&msp->ms_allocmap[txg & TXG_MASK], offset, size); + } mutex_exit(&msp->ms_lock); @@ -991,34 +959,44 @@ metaslab_claim_dva(spa_t *spa, const dva_t *dva, uint64_t txg) int metaslab_alloc(spa_t *spa, metaslab_class_t *mc, uint64_t psize, blkptr_t *bp, - int ndvas, uint64_t txg, blkptr_t *hintbp, boolean_t hintbp_avoid) + int ndvas, uint64_t txg, blkptr_t *hintbp, int flags) { dva_t *dva = bp->blk_dva; dva_t *hintdva = hintbp->blk_dva; - int d; int error = 0; - if (mc->mc_rotor == NULL) /* no vdevs in this class */ + ASSERT(bp->blk_birth == 0); + + spa_config_enter(spa, SCL_ALLOC, FTAG, RW_READER); + + if (mc->mc_rotor == NULL) { /* no vdevs in this class */ + spa_config_exit(spa, SCL_ALLOC, FTAG); return (ENOSPC); + } ASSERT(ndvas > 0 && ndvas <= spa_max_replication(spa)); ASSERT(BP_GET_NDVAS(bp) == 0); ASSERT(hintbp == NULL || ndvas <= BP_GET_NDVAS(hintbp)); - for (d = 0; d < ndvas; d++) { + for (int d = 0; d < ndvas; d++) { error = metaslab_alloc_dva(spa, mc, psize, dva, d, hintdva, - txg, hintbp_avoid); + txg, flags); if (error) { for (d--; d >= 0; d--) { metaslab_free_dva(spa, &dva[d], txg, B_TRUE); bzero(&dva[d], sizeof (dva_t)); } + spa_config_exit(spa, SCL_ALLOC, FTAG); return (error); } } ASSERT(error == 0); ASSERT(BP_GET_NDVAS(bp) == ndvas); + spa_config_exit(spa, SCL_ALLOC, FTAG); + + bp->blk_birth = txg; + return (0); } @@ -1027,12 +1005,16 @@ metaslab_free(spa_t *spa, const blkptr_t *bp, uint64_t txg, boolean_t now) { const dva_t *dva = bp->blk_dva; int ndvas = BP_GET_NDVAS(bp); - int d; ASSERT(!BP_IS_HOLE(bp)); + ASSERT(!now || bp->blk_birth >= spa->spa_syncing_txg); - for (d = 0; d < ndvas; d++) + spa_config_enter(spa, SCL_FREE, FTAG, RW_READER); + + for (int d = 0; d < ndvas; d++) metaslab_free_dva(spa, &dva[d], txg, now); + + spa_config_exit(spa, SCL_FREE, FTAG); } int @@ -1040,14 +1022,28 @@ metaslab_claim(spa_t *spa, const blkptr_t *bp, uint64_t txg) { const dva_t *dva = bp->blk_dva; int ndvas = BP_GET_NDVAS(bp); - int d, error; - int last_error = 0; + int error = 0; ASSERT(!BP_IS_HOLE(bp)); - for (d = 0; d < ndvas; d++) - if ((error = metaslab_claim_dva(spa, &dva[d], txg)) != 0) - last_error = error; + if (txg != 0) { + /* + * First do a dry run to make sure all DVAs are claimable, + * so we don't have to unwind from partial failures below. + */ + if ((error = metaslab_claim(spa, bp, 0)) != 0) + return (error); + } - return (last_error); + spa_config_enter(spa, SCL_ALLOC, FTAG, RW_READER); + + for (int d = 0; d < ndvas; d++) + if ((error = metaslab_claim_dva(spa, &dva[d], txg)) != 0) + break; + + spa_config_exit(spa, SCL_ALLOC, FTAG); + + ASSERT(error == 0 || txg == 0); + + return (error); } diff --git a/zfs/lib/libzpool/refcount.c b/zfs/lib/libzpool/refcount.c index d192394f8..f1b3b23fe 100644 --- a/zfs/lib/libzpool/refcount.c +++ b/zfs/lib/libzpool/refcount.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)refcount.c 1.2 07/08/02 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libdmu-ctl/rrwlock.c b/zfs/lib/libzpool/rrwlock.c similarity index 99% rename from zfs/lib/libdmu-ctl/rrwlock.c rename to zfs/lib/libzpool/rrwlock.c index c46ed8155..710685dbc 100644 --- a/zfs/lib/libdmu-ctl/rrwlock.c +++ b/zfs/lib/libzpool/rrwlock.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)rrwlock.c 1.1 07/10/24 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/sha256.c b/zfs/lib/libzpool/sha256.c index eb3a49bf3..ca7076cb6 100644 --- a/zfs/lib/libzpool/sha256.c +++ b/zfs/lib/libzpool/sha256.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)sha256.c 1.2 07/12/12 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/spa.c b/zfs/lib/libzpool/spa.c index f59db06db..fb1b96f8b 100644 --- a/zfs/lib/libzpool/spa.c +++ b/zfs/lib/libzpool/spa.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)spa.c 1.51 08/04/09 SMI" - /* * This file contains all the routines used when modifying on-disk SPA state. * This includes opening, importing, destroying, exporting a pool, and syncing a @@ -65,9 +63,18 @@ #include "zfs_prop.h" #include "zfs_comutil.h" -int zio_taskq_threads = 8; +int zio_taskq_threads[ZIO_TYPES][ZIO_TASKQ_TYPES] = { + /* ISSUE INTR */ + { 1, 1 }, /* ZIO_TYPE_NULL */ + { 1, 8 }, /* ZIO_TYPE_READ */ + { 8, 1 }, /* ZIO_TYPE_WRITE */ + { 1, 1 }, /* ZIO_TYPE_FREE */ + { 1, 1 }, /* ZIO_TYPE_CLAIM */ + { 1, 1 }, /* ZIO_TYPE_IOCTL */ +}; static void spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx); +static boolean_t spa_has_active_shared_spare(spa_t *spa); /* * ========================================================================== @@ -107,13 +114,14 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp) uint64_t used = spa_get_alloc(spa); uint64_t cap, version; zprop_source_t src = ZPROP_SRC_NONE; - char *cachefile; - size_t len; + spa_config_dirent_t *dp; + + ASSERT(MUTEX_HELD(&spa->spa_props_lock)); /* * readonly properties */ - spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa->spa_name, 0, src); + spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src); spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src); spa_prop_add_list(*nvp, ZPOOL_PROP_USED, NULL, used, src); spa_prop_add_list(*nvp, ZPOOL_PROP_AVAILABLE, NULL, size - used, src); @@ -139,19 +147,13 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp) spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root, 0, ZPROP_SRC_LOCAL); - if (spa->spa_config_dir != NULL) { - if (strcmp(spa->spa_config_dir, "none") == 0) { + if ((dp = list_head(&spa->spa_config_list)) != NULL) { + if (dp->scd_path == NULL) { spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, - spa->spa_config_dir, 0, ZPROP_SRC_LOCAL); - } else { - len = strlen(spa->spa_config_dir) + - strlen(spa->spa_config_file) + 2; - cachefile = kmem_alloc(len, KM_SLEEP); - (void) snprintf(cachefile, len, "%s/%s", - spa->spa_config_dir, spa->spa_config_file); + "none", 0, ZPROP_SRC_LOCAL); + } else if (strcmp(dp->scd_path, spa_config_path) != 0) { spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, - cachefile, 0, ZPROP_SRC_LOCAL); - kmem_free(cachefile, len); + dp->scd_path, 0, ZPROP_SRC_LOCAL); } } } @@ -169,12 +171,13 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp) VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0); + mutex_enter(&spa->spa_props_lock); + /* * Get properties from the spa config. */ spa_prop_get_config(spa, nvp); - mutex_enter(&spa->spa_props_lock); /* If no pool property object, no more prop to get. */ if (spa->spa_pool_props_object == 0) { mutex_exit(&spa->spa_props_lock); @@ -208,9 +211,8 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp) dp = spa_get_dsl(spa); rw_enter(&dp->dp_config_rwlock, RW_READER); - if (err = dsl_dataset_open_obj(dp, - za.za_first_integer, NULL, DS_MODE_NONE, - FTAG, &ds)) { + if (err = dsl_dataset_hold_obj(dp, + za.za_first_integer, FTAG, &ds)) { rw_exit(&dp->dp_config_rwlock); break; } @@ -219,7 +221,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp) MAXNAMELEN + strlen(MOS_DIR_NAME) + 1, KM_SLEEP); dsl_dataset_name(ds, strval); - dsl_dataset_close(ds, DS_MODE_NONE, FTAG); + dsl_dataset_rele(ds, FTAG); rw_exit(&dp->dp_config_rwlock); } else { strval = NULL; @@ -279,8 +281,6 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) zpool_prop_t prop; char *propname, *strval; uint64_t intval; - vdev_t *rvdev; - char *vdev_type; objset_t *os; char *slash; @@ -299,6 +299,7 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) case ZPOOL_PROP_DELEGATION: case ZPOOL_PROP_AUTOREPLACE: + case ZPOOL_PROP_LISTSNAPS: error = nvpair_value_uint64(elem, &intval); if (!error && intval > 1) error = EINVAL; @@ -311,15 +312,9 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) } /* - * A bootable filesystem can not be on a RAIDZ pool - * nor a striped pool with more than 1 device. + * Make sure the vdev config is bootable */ - rvdev = spa->spa_root_vdev; - vdev_type = - rvdev->vdev_child[0]->vdev_ops->vdev_op_type; - if (rvdev->vdev_children > 1 || - strcmp(vdev_type, VDEV_TYPE_RAIDZ) == 0 || - strcmp(vdev_type, VDEV_TYPE_MISSING) == 0) { + if (!vdev_is_bootable(spa->spa_root_vdev)) { error = ENOTSUP; break; } @@ -329,6 +324,8 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) error = nvpair_value_string(elem, &strval); if (!error) { + uint64_t compress; + if (strval == NULL || strval[0] == '\0') { objnum = zpool_prop_default_numeric( ZPOOL_PROP_BOOTFS); @@ -336,12 +333,22 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) } if (error = dmu_objset_open(strval, DMU_OST_ZFS, - DS_MODE_STANDARD | DS_MODE_READONLY, &os)) + DS_MODE_USER | DS_MODE_READONLY, &os)) break; - objnum = dmu_objset_id(os); + + /* We don't support gzip bootable datasets */ + if ((error = dsl_prop_get_integer(strval, + zfs_prop_to_name(ZFS_PROP_COMPRESSION), + &compress, NULL)) == 0 && + !BOOTFS_COMPRESS_VALID(compress)) { + error = ENOTSUP; + } else { + objnum = dmu_objset_id(os); + } dmu_objset_close(os); } break; + case ZPOOL_PROP_FAILUREMODE: error = nvpair_value_uint64(elem, &intval); if (!error && (intval < ZIO_FAILURE_MODE_WAIT || @@ -358,7 +365,7 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) * into thinking we encountered a property validation * error. */ - if (!error && spa_state(spa) == POOL_STATE_IO_FAILURE) { + if (!error && spa_suspended(spa)) { spa->spa_failmode = intval; error = EIO; } @@ -481,8 +488,6 @@ spa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub) static void spa_activate(spa_t *spa) { - int t; - ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); spa->spa_state = POOL_STATE_ACTIVE; @@ -490,19 +495,18 @@ spa_activate(spa_t *spa) spa->spa_normal_class = metaslab_class_create(); spa->spa_log_class = metaslab_class_create(); - for (t = 0; t < ZIO_TYPES; t++) { - spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue", - zio_taskq_threads, maxclsyspri, 50, INT_MAX, - TASKQ_PREPOPULATE); - spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr", - zio_taskq_threads, maxclsyspri, 50, INT_MAX, - TASKQ_PREPOPULATE); + for (int t = 0; t < ZIO_TYPES; t++) { + for (int q = 0; q < ZIO_TASKQ_TYPES; q++) { + spa->spa_zio_taskq[t][q] = taskq_create("spa_zio", + zio_taskq_threads[t][q], maxclsyspri, 50, + INT_MAX, TASKQ_PREPOPULATE); + } } - list_create(&spa->spa_dirty_list, sizeof (vdev_t), - offsetof(vdev_t, vdev_dirty_node)); - list_create(&spa->spa_zio_list, sizeof (zio_t), - offsetof(zio_t, zio_link_node)); + list_create(&spa->spa_config_dirty_list, sizeof (vdev_t), + offsetof(vdev_t, vdev_config_dirty_node)); + list_create(&spa->spa_state_dirty_list, sizeof (vdev_t), + offsetof(vdev_t, vdev_state_dirty_node)); txg_list_create(&spa->spa_vdev_txg_list, offsetof(struct vdev, vdev_txg_node)); @@ -521,8 +525,6 @@ spa_activate(spa_t *spa) static void spa_deactivate(spa_t *spa) { - int t; - ASSERT(spa->spa_sync_on == B_FALSE); ASSERT(spa->spa_dsl_pool == NULL); ASSERT(spa->spa_root_vdev == NULL); @@ -531,14 +533,14 @@ spa_deactivate(spa_t *spa) txg_list_destroy(&spa->spa_vdev_txg_list); - list_destroy(&spa->spa_dirty_list); - list_destroy(&spa->spa_zio_list); + list_destroy(&spa->spa_config_dirty_list); + list_destroy(&spa->spa_state_dirty_list); - for (t = 0; t < ZIO_TYPES; t++) { - taskq_destroy(spa->spa_zio_issue_taskq[t]); - taskq_destroy(spa->spa_zio_intr_taskq[t]); - spa->spa_zio_issue_taskq[t] = NULL; - spa->spa_zio_intr_taskq[t] = NULL; + for (int t = 0; t < ZIO_TYPES; t++) { + for (int q = 0; q < ZIO_TASKQ_TYPES; q++) { + taskq_destroy(spa->spa_zio_taskq[t][q]); + spa->spa_zio_taskq[t][q] = NULL; + } } metaslab_class_destroy(spa->spa_normal_class); @@ -579,8 +581,13 @@ spa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, if ((*vdp)->vdev_ops->vdev_op_leaf) return (0); - if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, - &child, &children) != 0) { + error = nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, + &child, &children); + + if (error == ENOENT) + return (0); + + if (error) { vdev_free(*vdp); *vdp = NULL; return (EINVAL); @@ -609,6 +616,8 @@ spa_unload(spa_t *spa) { int i; + ASSERT(MUTEX_HELD(&spa_namespace_lock)); + /* * Stop async tasks. */ @@ -623,10 +632,12 @@ spa_unload(spa_t *spa) } /* - * Wait for any outstanding prefetch I/O to complete. + * Wait for any outstanding async I/O to complete. */ - spa_config_enter(spa, RW_WRITER, FTAG); - spa_config_exit(spa, FTAG); + mutex_enter(&spa->spa_async_root_lock); + while (spa->spa_async_root_count != 0) + cv_wait(&spa->spa_async_root_cv, &spa->spa_async_root_lock); + mutex_exit(&spa->spa_async_root_lock); /* * Drop and purge level 2 cache @@ -659,6 +670,7 @@ spa_unload(spa_t *spa) nvlist_free(spa->spa_spares.sav_config); spa->spa_spares.sav_config = NULL; } + spa->spa_spares.sav_count = 0; for (i = 0; i < spa->spa_l2cache.sav_count; i++) vdev_free(spa->spa_l2cache.sav_vdevs[i]); @@ -671,6 +683,7 @@ spa_unload(spa_t *spa) nvlist_free(spa->spa_l2cache.sav_config); spa->spa_l2cache.sav_config = NULL; } + spa->spa_l2cache.sav_count = 0; spa->spa_async_suspended = 0; } @@ -689,6 +702,8 @@ spa_load_spares(spa_t *spa) int i; vdev_t *vd, *tvd; + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); + /* * First, close and free any existing spare vdevs. */ @@ -696,8 +711,8 @@ spa_load_spares(spa_t *spa) vd = spa->spa_spares.sav_vdevs[i]; /* Undo the call to spa_activate() below */ - if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid)) != NULL && - tvd->vdev_isspare) + if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid, + B_FALSE)) != NULL && tvd->vdev_isspare) spa_spare_remove(tvd); vdev_close(vd); vdev_free(vd); @@ -737,7 +752,8 @@ spa_load_spares(spa_t *spa) spa->spa_spares.sav_vdevs[i] = vd; - if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid)) != NULL) { + if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid, + B_FALSE)) != NULL) { if (!tvd->vdev_isspare) spa_spare_add(tvd); @@ -758,10 +774,11 @@ spa_load_spares(spa_t *spa) spa_spare_activate(tvd); } + vd->vdev_top = vd; + if (vdev_open(vd) != 0) continue; - vd->vdev_top = vd; if (vdev_validate_aux(vd) == 0) spa_spare_add(vd); } @@ -799,10 +816,12 @@ spa_load_l2cache(spa_t *spa) nvlist_t **l2cache; uint_t nl2cache; int i, j, oldnvdevs; - uint64_t guid; + uint64_t guid, size; vdev_t *vd, **oldvdevs, **newvdevs; spa_aux_vdev_t *sav = &spa->spa_l2cache; + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); + if (sav->sav_config != NULL) { VERIFY(nvlist_lookup_nvlist_array(sav->sav_config, ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0); @@ -851,22 +870,21 @@ spa_load_l2cache(spa_t *spa) */ spa_l2cache_add(vd); + vd->vdev_top = vd; + vd->vdev_aux = sav; + + spa_l2cache_activate(vd); + if (vdev_open(vd) != 0) continue; - vd->vdev_top = vd; (void) vdev_validate_aux(vd); if (!vdev_is_dead(vd)) { - uint64_t size; size = vdev_get_rsize(vd); - ASSERT3U(size, >, 0); - if (spa_mode & FWRITE) { - l2arc_add_vdev(spa, vd, - VDEV_LABEL_START_SIZE, - size - VDEV_LABEL_START_SIZE); - } - spa_l2cache_activate(vd); + l2arc_add_vdev(spa, vd, + VDEV_LABEL_START_SIZE, + size - VDEV_LABEL_START_SIZE); } } } @@ -879,9 +897,10 @@ spa_load_l2cache(spa_t *spa) vd = oldvdevs[i]; if (vd != NULL) { - if (spa_mode & FWRITE && + if ((spa_mode & FWRITE) && spa_l2cache_exists(vd->vdev_guid, &pool) && - pool != 0ULL) { + pool != 0ULL && + l2arc_vdev_present(vd)) { l2arc_remove_vdev(vd); } (void) vdev_close(vd); @@ -958,6 +977,32 @@ spa_check_removed(vdev_t *vd) } } +/* + * Check for missing log devices + */ +int +spa_check_logs(spa_t *spa) +{ + switch (spa->spa_log_state) { + case SPA_LOG_MISSING: + /* need to recheck in case slog has been restored */ + case SPA_LOG_UNKNOWN: + if (dmu_objset_find(spa->spa_name, zil_check_log_chain, NULL, + DS_FIND_CHILDREN)) { + spa->spa_log_state = SPA_LOG_MISSING; + return (1); + } + break; + + case SPA_LOG_CLEAR: + (void) dmu_objset_find(spa->spa_name, zil_clear_log_chain, NULL, + DS_FIND_CHILDREN); + break; + } + spa->spa_log_state = SPA_LOG_GOOD; + return (0); +} + /* * Load an existing storage pool, using the pool's builtin spa_config as a * source of configuration information. @@ -972,8 +1017,10 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) uint64_t config_cache_txg = spa->spa_config_txg; uint64_t pool_guid; uint64_t version; - zio_t *zio; uint64_t autoreplace = 0; + char *ereport = FM_EREPORT_ZFS_POOL; + + ASSERT(MUTEX_HELD(&spa_namespace_lock)); spa->spa_load_state = state; @@ -1006,10 +1053,10 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) * value that will be returned by spa_version() since parsing the * configuration requires knowing the version number. */ - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); spa->spa_ubsync.ub_version = version; error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_LOAD); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); if (error != 0) goto out; @@ -1020,18 +1067,19 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) /* * Try to open all vdevs, loading each label in the process. */ + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); error = vdev_open(rvd); + spa_config_exit(spa, SCL_ALL, FTAG); if (error != 0) goto out; /* * Validate the labels for all leaf vdevs. We need to grab the config - * lock because all label I/O is done with the ZIO_FLAG_CONFIG_HELD - * flag. + * lock because all label I/O is done with ZIO_FLAG_CONFIG_WRITER. */ - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); error = vdev_validate(rvd); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); if (error != 0) goto out; @@ -1044,12 +1092,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) /* * Find the best uberblock. */ - bzero(ub, sizeof (uberblock_t)); - - zio = zio_root(spa, NULL, NULL, - ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE); - vdev_uberblock_load(zio, rvd, ub); - error = zio_wait(zio); + vdev_uberblock_load(NULL, rvd, ub); /* * If we weren't able to find a single valid uberblock, return failure. @@ -1116,8 +1159,8 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) goto out; } - if (nvlist_lookup_uint64(newconfig, ZPOOL_CONFIG_HOSTID, - &hostid) == 0) { + if (!spa_is_root(spa) && nvlist_lookup_uint64(newconfig, + ZPOOL_CONFIG_HOSTID, &hostid) == 0) { char *hostname; unsigned long myhostid = 0; @@ -1129,9 +1172,9 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) (unsigned long)hostid != myhostid) { cmn_err(CE_WARN, "pool '%s' could not be " "loaded as it was last accessed by " - "another system (host: %s hostid: 0x%lx). " + "another system (host: %s hostid: 0x%lx). " "See: http://www.sun.com/msg/ZFS-8000-EY", - spa->spa_name, hostname, + spa_name(spa), hostname, (unsigned long)hostid); error = EBADF; goto out; @@ -1229,9 +1272,9 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) goto out; } - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); spa_load_spares(spa); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); } /* @@ -1257,11 +1300,20 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) goto out; } - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); spa_load_l2cache(spa); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); } + if (spa_check_logs(spa)) { + vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, + VDEV_AUX_BAD_LOG); + error = ENXIO; + ereport = FM_EREPORT_ZFS_LOG_REPLAY; + goto out; + } + + spa->spa_delegation = zpool_prop_default_numeric(ZPOOL_PROP_DELEGATION); error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT, @@ -1311,9 +1363,9 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) /* * Propagate the leaf DTLs we just loaded all the way up the tree. */ - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); vdev_dtl_reassess(rvd, 0, 0, B_FALSE); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); /* * Check the state of the root vdev. If it can't be opened, it @@ -1335,7 +1387,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) */ tx = dmu_tx_create_assigned(spa_get_dsl(spa), spa_first_txg(spa)); - (void) dmu_objset_find(spa->spa_name, + (void) dmu_objset_find(spa_name(spa), zil_claim, tx, DS_FIND_CHILDREN); dmu_tx_commit(tx); @@ -1369,8 +1421,9 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) error = 0; out: + spa->spa_minref = refcount_count(&spa->spa_refcount); if (error && error != EBADF) - zfs_ereport_post(FM_EREPORT_ZFS_POOL, spa, NULL, NULL, 0, 0); + zfs_ereport_post(ereport, spa, NULL, NULL, 0, 0); spa->spa_load_state = SPA_LOAD_NONE; spa->spa_ena = 0; @@ -1394,7 +1447,6 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t **config) { spa_t *spa; int error; - int loaded = B_FALSE; int locked = B_FALSE; *spapp = NULL; @@ -1429,11 +1481,10 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t **config) * this is the case, the config cache is out of sync and * we should remove the pool from the namespace. */ - zfs_post_ok(spa, NULL); spa_unload(spa); spa_deactivate(spa); + spa_config_sync(spa, B_TRUE, B_TRUE); spa_remove(spa); - spa_config_sync(); if (locked) mutex_exit(&spa_namespace_lock); return (ENOENT); @@ -1445,12 +1496,9 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t **config) * information: the state of each vdev after the * attempted vdev_open(). Return this to the user. */ - if (config != NULL && spa->spa_root_vdev != NULL) { - spa_config_enter(spa, RW_READER, FTAG); + if (config != NULL && spa->spa_root_vdev != NULL) *config = spa_config_generate(spa, NULL, -1ULL, B_TRUE); - spa_config_exit(spa, FTAG); - } spa_unload(spa); spa_deactivate(spa); spa->spa_last_open_failed = B_TRUE; @@ -1459,31 +1507,19 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t **config) *spapp = NULL; return (error); } else { - zfs_post_ok(spa, NULL); spa->spa_last_open_failed = B_FALSE; } - - loaded = B_TRUE; } spa_open_ref(spa, tag); - /* - * If we just loaded the pool, resilver anything that's out of date. - */ - if (loaded && (spa_mode & FWRITE)) - VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0); - if (locked) mutex_exit(&spa_namespace_lock); *spapp = spa; - if (config != NULL) { - spa_config_enter(spa, RW_READER, FTAG); + if (config != NULL) *config = spa_config_generate(spa, NULL, -1ULL, B_TRUE); - spa_config_exit(spa, FTAG); - } return (0); } @@ -1557,7 +1593,8 @@ spa_add_spares(spa_t *spa, nvlist_t *config) for (i = 0; i < nspares; i++) { VERIFY(nvlist_lookup_uint64(spares[i], ZPOOL_CONFIG_GUID, &guid) == 0); - if (spa_spare_exists(guid, &pool) && pool != 0ULL) { + if (spa_spare_exists(guid, &pool, NULL) && + pool != 0ULL) { VERIFY(nvlist_lookup_uint64_array( spares[i], ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &vsc) == 0); @@ -1585,7 +1622,7 @@ spa_add_l2cache(spa_t *spa, nvlist_t *config) if (spa->spa_l2cache.sav_count == 0) return; - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER); VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); @@ -1621,7 +1658,7 @@ spa_add_l2cache(spa_t *spa, nvlist_t *config) } } - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_CONFIG, FTAG); } int @@ -1637,6 +1674,10 @@ spa_get_stats(const char *name, nvlist_t **config, char *altroot, size_t buflen) VERIFY(nvlist_add_uint64(*config, ZPOOL_CONFIG_ERRCOUNT, spa_get_errlog_size(spa)) == 0); + if (spa_suspended(spa)) + VERIFY(nvlist_add_uint64(*config, + ZPOOL_CONFIG_SUSPENDED, spa->spa_failmode) == 0); + spa_add_spares(spa, *config); spa_add_l2cache(spa, *config); } @@ -1682,6 +1723,8 @@ spa_validate_aux_devs(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode, vdev_t *vd; int error; + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); + /* * It's acceptable to have no devs specified. */ @@ -1717,14 +1760,16 @@ spa_validate_aux_devs(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode, } /* - * The L2ARC currently only supports disk devices. + * The L2ARC currently only supports disk devices in + * kernel context. For user-level testing, we allow it. */ +#ifdef _KERNEL if ((strcmp(config, ZPOOL_CONFIG_L2CACHE) == 0) && strcmp(vd->vdev_ops->vdev_op_type, VDEV_TYPE_DISK) != 0) { error = ENOTBLK; goto out; } - +#endif vd->vdev_top = vd; if ((error = vdev_open(vd)) == 0 && @@ -1753,6 +1798,8 @@ spa_validate_aux(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode) { int error; + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); + if ((error = spa_validate_aux_devs(spa, nvroot, crtxg, mode, &spa->spa_spares, ZPOOL_CONFIG_SPARES, SPA_VERSION_SPARES, VDEV_LABEL_SPARE)) != 0) { @@ -1826,8 +1873,9 @@ spa_l2cache_drop(spa_t *spa) vd = sav->sav_vdevs[i]; ASSERT(vd != NULL); - if (spa_mode & FWRITE && - spa_l2cache_exists(vd->vdev_guid, &pool) && pool != 0ULL) { + if ((spa_mode & FWRITE) && + spa_l2cache_exists(vd->vdev_guid, &pool) && pool != 0ULL && + l2arc_vdev_present(vd)) { l2arc_remove_vdev(vd); } if (vd->vdev_isl2cache) @@ -1842,7 +1890,7 @@ spa_l2cache_drop(spa_t *spa) */ int spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, - const char *history_str) + const char *history_str, nvlist_t *zplprops) { spa_t *spa; char *altroot = NULL; @@ -1878,6 +1926,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, spa_unload(spa); spa_deactivate(spa); spa_remove(spa); + mutex_exit(&spa_namespace_lock); return (error); } @@ -1891,7 +1940,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, /* * Create the root vdev. */ - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_ADD); @@ -1910,7 +1959,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, vdev_config_dirty(rvd); } - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); if (error != 0) { spa_unload(spa); @@ -1929,9 +1978,9 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, KM_SLEEP) == 0); VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config, ZPOOL_CONFIG_SPARES, spares, nspares) == 0); - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); spa_load_spares(spa); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); spa->spa_spares.sav_sync = B_TRUE; } @@ -1944,13 +1993,13 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, NV_UNIQUE_NAME, KM_SLEEP) == 0); VERIFY(nvlist_add_nvlist_array(spa->spa_l2cache.sav_config, ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0); - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); spa_load_l2cache(spa); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); spa->spa_l2cache.sav_sync = B_TRUE; } - spa->spa_dsl_pool = dp = dsl_pool_create(spa, txg); + spa->spa_dsl_pool = dp = dsl_pool_create(spa, zplprops, txg); spa->spa_meta_objset = dp->dp_meta_objset; tx = dmu_tx_create_assigned(dp, txg); @@ -1959,7 +2008,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, * Create the pool config object. */ spa->spa_config_object = dmu_object_alloc(spa->spa_meta_objset, - DMU_OT_PACKED_NVLIST, 1 << 14, + DMU_OT_PACKED_NVLIST, SPA_CONFIG_BLOCKSIZE, DMU_OT_PACKED_NVLIST_SIZE, sizeof (uint64_t), tx); if (zap_add(spa->spa_meta_objset, @@ -2020,13 +2069,15 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, */ txg_wait_synced(spa->spa_dsl_pool, txg); - spa_config_sync(); + spa_config_sync(spa, B_FALSE, B_TRUE); if (version >= SPA_VERSION_ZPOOL_HISTORY && history_str != NULL) (void) spa_history_log(spa, history_str, LOG_CMD_POOL_CREATE); mutex_exit(&spa_namespace_lock); + spa->spa_minref = refcount_count(&spa->spa_refcount); + return (0); } @@ -2036,23 +2087,32 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, */ static int spa_import_common(const char *pool, nvlist_t *config, nvlist_t *props, - boolean_t isroot) + boolean_t isroot, boolean_t allowfaulted) { spa_t *spa; char *altroot = NULL; - int error; + int error, loaderr; nvlist_t *nvroot; nvlist_t **spares, **l2cache; uint_t nspares, nl2cache; - int mosconfig = isroot? B_FALSE : B_TRUE; /* * If a pool with this name exists, return failure. */ mutex_enter(&spa_namespace_lock); - if (spa_lookup(pool) != NULL) { - mutex_exit(&spa_namespace_lock); - return (EEXIST); + if ((spa = spa_lookup(pool)) != NULL) { + if (isroot) { + /* + * Remove the existing root pool from the + * namespace so that we can replace it with + * the correct config we just read in. + */ + ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); + spa_remove(spa); + } else { + mutex_exit(&spa_namespace_lock); + return (EEXIST); + } } /* @@ -2063,14 +2123,19 @@ spa_import_common(const char *pool, nvlist_t *config, nvlist_t *props, spa = spa_add(pool, altroot); spa_activate(spa); + if (allowfaulted) + spa->spa_import_faulted = B_TRUE; + spa->spa_is_root = isroot; + /* * Pass off the heavy lifting to spa_load(). - * Pass TRUE for mosconfig because the user-supplied config - * is actually the one to trust when doing an import. + * Pass TRUE for mosconfig (unless this is a root pool) because + * the user-supplied config is actually the one to trust when + * doing an import. */ - error = spa_load(spa, config, SPA_LOAD_IMPORT, mosconfig); + loaderr = error = spa_load(spa, config, SPA_LOAD_IMPORT, !isroot); - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); /* * Toss any existing sparelist, as it doesn't have any validity anymore, * and conflicts with spa_has_spare(). @@ -2093,12 +2158,28 @@ spa_import_common(const char *pool, nvlist_t *config, nvlist_t *props, if (error == 0) error = spa_validate_aux(spa, nvroot, -1ULL, VDEV_ALLOC_L2CACHE); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); if (error != 0 || (props && (error = spa_prop_set(spa, props)))) { - spa_unload(spa); - spa_deactivate(spa); - spa_remove(spa); + if (loaderr != 0 && loaderr != EINVAL && allowfaulted) { + /* + * If we failed to load the pool, but 'allowfaulted' is + * set, then manually set the config as if the config + * passed in was specified in the cache file. + */ + error = 0; + spa->spa_import_faulted = B_FALSE; + if (spa->spa_config == NULL) + spa->spa_config = spa_config_generate(spa, + NULL, -1ULL, B_TRUE); + spa_unload(spa); + spa_deactivate(spa); + spa_config_sync(spa, B_FALSE, B_TRUE); + } else { + spa_unload(spa); + spa_deactivate(spa); + spa_remove(spa); + } mutex_exit(&spa_namespace_lock); return (error); } @@ -2117,9 +2198,9 @@ spa_import_common(const char *pool, nvlist_t *config, nvlist_t *props, NV_UNIQUE_NAME, KM_SLEEP) == 0); VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config, ZPOOL_CONFIG_SPARES, spares, nspares) == 0); - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); spa_load_spares(spa); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); spa->spa_spares.sav_sync = B_TRUE; } if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, @@ -2132,24 +2213,20 @@ spa_import_common(const char *pool, nvlist_t *config, nvlist_t *props, NV_UNIQUE_NAME, KM_SLEEP) == 0); VERIFY(nvlist_add_nvlist_array(spa->spa_l2cache.sav_config, ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0); - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); spa_load_l2cache(spa); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); spa->spa_l2cache.sav_sync = B_TRUE; } - /* - * Update the config cache to include the newly-imported pool. - */ - if (spa_mode & FWRITE) + if (spa_mode & FWRITE) { + /* + * Update the config cache to include the newly-imported pool. + */ spa_config_update_common(spa, SPA_CONFIG_UPDATE_POOL, isroot); + } - /* - * Resilver anything that's out of date. - */ - if (!isroot && (spa_mode & FWRITE)) - VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0); - + spa->spa_import_faulted = B_FALSE; mutex_exit(&spa_namespace_lock); return (0); @@ -2197,27 +2274,27 @@ spa_build_rootpool_config(nvlist_t *config) * Get the root pool information from the root disk, then import the root pool * during the system boot up time. */ -extern nvlist_t *vdev_disk_read_rootlabel(char *); +extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **); -void -spa_check_rootconf(char *devpath, char **bestdev, nvlist_t **bestconf, +int +spa_check_rootconf(char *devpath, char *devid, nvlist_t **bestconf, uint64_t *besttxg) { nvlist_t *config; uint64_t txg; + int error; - if ((config = vdev_disk_read_rootlabel(devpath)) == NULL) - return; + if (error = vdev_disk_read_rootlabel(devpath, devid, &config)) + return (error); VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) == 0); - if (txg > *besttxg) { - *besttxg = txg; - if (*bestconf != NULL) - nvlist_free(*bestconf); + if (bestconf != NULL) *bestconf = config; - *bestdev = devpath; - } + else + nvlist_free(config); + *besttxg = txg; + return (0); } boolean_t @@ -2227,20 +2304,99 @@ spa_rootdev_validate(nvlist_t *nv) if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 || nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 || - nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DEGRADED, &ival) == 0 || nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0) return (B_FALSE); return (B_TRUE); } + +/* + * Given the boot device's physical path or devid, check if the device + * is in a valid state. If so, return the configuration from the vdev + * label. + */ +int +spa_get_rootconf(char *devpath, char *devid, nvlist_t **bestconf) +{ + nvlist_t *conf = NULL; + uint64_t txg = 0; + nvlist_t *nvtop, **child; + char *type; + char *bootpath = NULL; + uint_t children, c; + char *tmp; + int error; + + if (devpath && ((tmp = strchr(devpath, ' ')) != NULL)) + *tmp = '\0'; + if (error = spa_check_rootconf(devpath, devid, &conf, &txg)) { + cmn_err(CE_NOTE, "error reading device label"); + return (error); + } + if (txg == 0) { + cmn_err(CE_NOTE, "this device is detached"); + nvlist_free(conf); + return (EINVAL); + } + + VERIFY(nvlist_lookup_nvlist(conf, ZPOOL_CONFIG_VDEV_TREE, + &nvtop) == 0); + VERIFY(nvlist_lookup_string(nvtop, ZPOOL_CONFIG_TYPE, &type) == 0); + + if (strcmp(type, VDEV_TYPE_DISK) == 0) { + if (spa_rootdev_validate(nvtop)) { + goto out; + } else { + nvlist_free(conf); + return (EINVAL); + } + } + + ASSERT(strcmp(type, VDEV_TYPE_MIRROR) == 0); + + VERIFY(nvlist_lookup_nvlist_array(nvtop, ZPOOL_CONFIG_CHILDREN, + &child, &children) == 0); + + /* + * Go thru vdevs in the mirror to see if the given device + * has the most recent txg. Only the device with the most + * recent txg has valid information and should be booted. + */ + for (c = 0; c < children; c++) { + char *cdevid, *cpath; + uint64_t tmptxg; + + if (nvlist_lookup_string(child[c], ZPOOL_CONFIG_PHYS_PATH, + &cpath) != 0) + return (EINVAL); + if (nvlist_lookup_string(child[c], ZPOOL_CONFIG_DEVID, + &cdevid) != 0) + return (EINVAL); + if ((spa_check_rootconf(cpath, cdevid, NULL, + &tmptxg) == 0) && (tmptxg > txg)) { + txg = tmptxg; + VERIFY(nvlist_lookup_string(child[c], + ZPOOL_CONFIG_PATH, &bootpath) == 0); + } + } + + /* Does the best device match the one we've booted from? */ + if (bootpath) { + cmn_err(CE_NOTE, "try booting from '%s'", bootpath); + return (EINVAL); + } +out: + *bestconf = conf; + return (0); +} + /* * Import a root pool. * - * For x86. devpath_list will consist the physpath name of the vdev in a single - * disk root pool or a list of physnames for the vdevs in a mirrored rootpool. - * e.g. - * "/pci@1f,0/ide@d/disk@0,0:a /pci@1f,o/ide@d/disk@2,0:a" + * For x86. devpath_list will consist of devid and/or physpath name of + * the vdev (e.g. "id1,sd@SSEAGATE..." or "/pci@1f,0/ide@d/disk@0,0:a"). + * The GRUB "findroot" command will return the vdev we should boot. * * For Sparc, devpath_list consists the physpath name of the booting device * no matter the rootpool is a single device pool or a mirrored pool. @@ -2248,10 +2404,9 @@ spa_rootdev_validate(nvlist_t *nv) * "/pci@1f,0/ide@d/disk@0,0:a" */ int -spa_import_rootpool(char *devpath_list) +spa_import_rootpool(char *devpath, char *devid) { nvlist_t *conf = NULL; - char *dev = NULL; char *pname; int error; @@ -2259,7 +2414,7 @@ spa_import_rootpool(char *devpath_list) * Get the vdev pathname and configuation from the most * recently updated vdev (highest txg). */ - if (error = spa_get_rootconf(devpath_list, &dev, &conf)) + if (error = spa_get_rootconf(devpath, devid, &conf)) goto msg_out; /* @@ -2269,20 +2424,25 @@ spa_import_rootpool(char *devpath_list) VERIFY(nvlist_lookup_string(conf, ZPOOL_CONFIG_POOL_NAME, &pname) == 0); - error = spa_import_common(pname, conf, NULL, TRUE); - if (error == EEXIST) - error = 0; + /* + * We specify 'allowfaulted' for this to be treated like spa_open() + * instead of spa_import(). This prevents us from marking vdevs as + * persistently unavailable, and generates FMA ereports as if it were a + * pool open, not import. + */ + error = spa_import_common(pname, conf, NULL, B_TRUE, B_TRUE); + ASSERT(error != EEXIST); nvlist_free(conf); return (error); msg_out: - cmn_err(CE_NOTE, "\n\n" + cmn_err(CE_NOTE, "\n" " *************************************************** \n" " * This device is not bootable! * \n" " * It is either offlined or detached or faulted. * \n" " * Please try to boot from a different device. * \n" - " *************************************************** \n\n"); + " *************************************************** "); return (error); } @@ -2294,9 +2454,16 @@ msg_out: int spa_import(const char *pool, nvlist_t *config, nvlist_t *props) { - return (spa_import_common(pool, config, props, FALSE)); + return (spa_import_common(pool, config, props, B_FALSE, B_FALSE)); } +int +spa_import_faulted(const char *pool, nvlist_t *config, nvlist_t *props) +{ + return (spa_import_common(pool, config, props, B_FALSE, B_TRUE)); +} + + /* * This (illegal) pool name is used when temporarily importing a spa_t in order * to get the vdev stats associated with the imported devices. @@ -2335,9 +2502,7 @@ spa_tryimport(nvlist_t *tryconfig) * If 'tryconfig' was at least parsable, return the current config. */ if (spa->spa_root_vdev != NULL) { - spa_config_enter(spa, RW_READER, FTAG); config = spa_config_generate(spa, NULL, -1ULL, B_TRUE); - spa_config_exit(spa, FTAG); VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME, poolname) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, @@ -2357,7 +2522,7 @@ spa_tryimport(nvlist_t *tryconfig) * We have to play games with the name since the * pool was opened as TRYIMPORT_NAME. */ - if (dsl_dsobj_to_dsname(spa->spa_name, + if (dsl_dsobj_to_dsname(spa_name(spa), spa->spa_bootfs, tmpname) == 0) { char *cp; char *dsname = kmem_alloc(MAXPATHLEN, KM_SLEEP); @@ -2401,7 +2566,8 @@ spa_tryimport(nvlist_t *tryconfig) * configuration from the cache afterwards. */ static int -spa_export_common(char *pool, int new_state, nvlist_t **oldconfig) +spa_export_common(char *pool, int new_state, nvlist_t **oldconfig, + boolean_t force) { spa_t *spa; @@ -2436,7 +2602,6 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig) * Objsets may be open only because they're dirty, so we * have to force it to sync before checking spa_refcnt. */ - spa_scrub_suspend(spa); txg_wait_synced(spa->spa_dsl_pool, 0); /* @@ -2447,14 +2612,23 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig) if (!spa_refcount_zero(spa) || (spa->spa_inject_ref != 0 && new_state != POOL_STATE_UNINITIALIZED)) { - spa_scrub_resume(spa); spa_async_resume(spa); mutex_exit(&spa_namespace_lock); return (EBUSY); } - spa_scrub_resume(spa); - VERIFY(spa_scrub(spa, POOL_SCRUB_NONE, B_TRUE) == 0); + /* + * A pool cannot be exported if it has an active shared spare. + * This is to prevent other pools stealing the active spare + * from an exported pool. At user's own will, such pool can + * be forcedly exported. + */ + if (!force && new_state == POOL_STATE_EXPORTED && + spa_has_active_shared_spare(spa)) { + spa_async_resume(spa); + mutex_exit(&spa_namespace_lock); + return (EXDEV); + } /* * We want this to be reflected on every label, @@ -2462,11 +2636,11 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig) * final sync that pushes these changes out. */ if (new_state != POOL_STATE_UNINITIALIZED) { - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); spa->spa_state = new_state; spa->spa_final_txg = spa_last_synced_txg(spa) + 1; vdev_config_dirty(spa->spa_root_vdev); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); } } @@ -2481,10 +2655,8 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig) VERIFY(nvlist_dup(spa->spa_config, oldconfig, 0) == 0); if (new_state != POOL_STATE_UNINITIALIZED) { - spa_config_check(spa->spa_config_dir, - spa->spa_config_file); + spa_config_sync(spa, B_TRUE, B_TRUE); spa_remove(spa); - spa_config_sync(); } mutex_exit(&spa_namespace_lock); @@ -2497,16 +2669,16 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig) int spa_destroy(char *pool) { - return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL)); + return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL, B_FALSE)); } /* * Export a storage pool. */ int -spa_export(char *pool, nvlist_t **oldconfig) +spa_export(char *pool, nvlist_t **oldconfig, boolean_t force) { - return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig)); + return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig, force)); } /* @@ -2516,10 +2688,10 @@ spa_export(char *pool, nvlist_t **oldconfig) int spa_reset(char *pool) { - return (spa_export_common(pool, POOL_STATE_UNINITIALIZED, NULL)); + return (spa_export_common(pool, POOL_STATE_UNINITIALIZED, NULL, + B_FALSE)); } - /* * ========================================================================== * Device manipulation @@ -2545,7 +2717,7 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot) VDEV_ALLOC_ADD)) != 0) return (spa_vdev_exit(spa, NULL, txg, error)); - spa->spa_pending_vdev = vd; + spa->spa_pending_vdev = vd; /* spa_vdev_exit() will clear this */ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, &spares, &nspares) != 0) @@ -2555,28 +2727,19 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot) &nl2cache) != 0) nl2cache = 0; - if (vd->vdev_children == 0 && nspares == 0 && nl2cache == 0) { - spa->spa_pending_vdev = NULL; + if (vd->vdev_children == 0 && nspares == 0 && nl2cache == 0) return (spa_vdev_exit(spa, vd, txg, EINVAL)); - } - if (vd->vdev_children != 0) { - if ((error = vdev_create(vd, txg, B_FALSE)) != 0) { - spa->spa_pending_vdev = NULL; - return (spa_vdev_exit(spa, vd, txg, error)); - } - } + if (vd->vdev_children != 0 && + (error = vdev_create(vd, txg, B_FALSE)) != 0) + return (spa_vdev_exit(spa, vd, txg, error)); /* * We must validate the spares and l2cache devices after checking the * children. Otherwise, vdev_inuse() will blindly overwrite the spare. */ - if ((error = spa_validate_aux(spa, nvroot, txg, VDEV_ALLOC_ADD)) != 0) { - spa->spa_pending_vdev = NULL; + if ((error = spa_validate_aux(spa, nvroot, txg, VDEV_ALLOC_ADD)) != 0) return (spa_vdev_exit(spa, vd, txg, error)); - } - - spa->spa_pending_vdev = NULL; /* * Transfer each new top-level vdev from vd to rvd. @@ -2642,15 +2805,17 @@ int spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing) { uint64_t txg, open_txg; - int error; vdev_t *rvd = spa->spa_root_vdev; vdev_t *oldvd, *newvd, *newrootvd, *pvd, *tvd; vdev_ops_t *pvops; - int is_log; + dmu_tx_t *tx; + char *oldvdpath, *newvdpath; + int newvd_isspare; + int error; txg = spa_vdev_enter(spa); - oldvd = vdev_lookup_by_guid(rvd, guid); + oldvd = spa_lookup_by_guid(spa, guid, B_FALSE); if (oldvd == NULL) return (spa_vdev_exit(spa, NULL, txg, ENODEV)); @@ -2678,8 +2843,7 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing) /* * Spares can't replace logs */ - is_log = oldvd->vdev_islog; - if (is_log && newvd->vdev_isspare) + if (oldvd->vdev_top->vdev_islog && newvd->vdev_isspare) return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP)); if (!replacing) { @@ -2795,6 +2959,9 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing) if (newvd->vdev_isspare) spa_spare_activate(newvd); + oldvdpath = spa_strdup(oldvd->vdev_path); + newvdpath = spa_strdup(newvd->vdev_path); + newvd_isspare = newvd->vdev_isspare; /* * Mark newvd's DTL dirty in this txg. @@ -2803,13 +2970,25 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing) (void) spa_vdev_exit(spa, newrootvd, open_txg, 0); + tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir); + if (dmu_tx_assign(tx, TXG_WAIT) == 0) { + spa_history_internal_log(LOG_POOL_VDEV_ATTACH, spa, tx, + CRED(), "%s vdev=%s %s vdev=%s", + replacing && newvd_isspare ? "spare in" : + replacing ? "replace" : "attach", newvdpath, + replacing ? "for" : "to", oldvdpath); + dmu_tx_commit(tx); + } else { + dmu_tx_abort(tx); + } + + spa_strfree(oldvdpath); + spa_strfree(newvdpath); + /* - * Kick off a resilver to update newvd. We need to grab the namespace - * lock because spa_scrub() needs to post a sysevent with the pool name. + * Kick off a resilver to update newvd. */ - mutex_enter(&spa_namespace_lock); - VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0); - mutex_exit(&spa_namespace_lock); + VERIFY3U(spa_scrub(spa, POOL_SCRUB_RESILVER), ==, 0); return (0); } @@ -2828,10 +3007,11 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, int replace_done) vdev_t *vd, *pvd, *cvd, *tvd; boolean_t unspare = B_FALSE; uint64_t unspare_guid; + size_t len; txg = spa_vdev_enter(spa); - vd = vdev_lookup_by_guid(rvd, guid); + vd = spa_lookup_by_guid(spa, guid, B_FALSE); if (vd == NULL) return (spa_vdev_exit(spa, NULL, txg, ENODEV)); @@ -2895,14 +3075,27 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, int replace_done) break; } - /* - * If we are a replacing or spare vdev, then we can always detach the - * latter child, as that is how one cancels the operation. - */ - if ((pvd->vdev_ops == &vdev_mirror_ops || vd->vdev_id != 1) && - c == pvd->vdev_children) + if (c == pvd->vdev_children) return (spa_vdev_exit(spa, NULL, txg, EBUSY)); + /* + * If we are detaching the second disk from a replacing vdev, then + * check to see if we changed the original vdev's path to have "/old" + * at the end in spa_vdev_attach(). If so, undo that change now. + */ + if (pvd->vdev_ops == &vdev_replacing_ops && vd->vdev_id == 1 && + pvd->vdev_child[0]->vdev_path != NULL && + pvd->vdev_child[1]->vdev_path != NULL) { + ASSERT(pvd->vdev_child[1] == vd); + cvd = pvd->vdev_child[0]; + len = strlen(vd->vdev_path); + if (strncmp(cvd->vdev_path, vd->vdev_path, len) == 0 && + strcmp(cvd->vdev_path + len, "/old") == 0) { + spa_strfree(cvd->vdev_path); + cvd->vdev_path = spa_strdup(vd->vdev_path); + } + } + /* * If we are detaching the original disk from a spare, then it implies * that the spare should become a real disk, and be removed from the @@ -3000,8 +3193,11 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, int replace_done) while ((spa = spa_next(spa)) != NULL) { if (spa->spa_state != POOL_STATE_ACTIVE) continue; - + spa_open_ref(spa, FTAG); + mutex_exit(&spa_namespace_lock); (void) spa_vdev_remove(spa, unspare_guid, B_TRUE); + mutex_enter(&spa_namespace_lock); + spa_close(spa, FTAG); } mutex_exit(&spa_namespace_lock); } @@ -3009,121 +3205,45 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, int replace_done) return (error); } -/* - * Remove a spares vdev from the nvlist config. - */ -static int -spa_remove_spares(spa_aux_vdev_t *sav, uint64_t guid, boolean_t unspare, - nvlist_t **spares, int nspares, vdev_t *vd) +static nvlist_t * +spa_nvlist_lookup_by_guid(nvlist_t **nvpp, int count, uint64_t target_guid) { - nvlist_t *nv, **newspares; - int i, j; + for (int i = 0; i < count; i++) { + uint64_t guid; - nv = NULL; - for (i = 0; i < nspares; i++) { - uint64_t theguid; + VERIFY(nvlist_lookup_uint64(nvpp[i], ZPOOL_CONFIG_GUID, + &guid) == 0); - VERIFY(nvlist_lookup_uint64(spares[i], - ZPOOL_CONFIG_GUID, &theguid) == 0); - if (theguid == guid) { - nv = spares[i]; - break; - } + if (guid == target_guid) + return (nvpp[i]); } - /* - * Only remove the hot spare if it's not currently in use in this pool. - */ - if (nv == NULL && vd == NULL) - return (ENOENT); - - if (nv == NULL && vd != NULL) - return (ENOTSUP); - - if (!unspare && nv != NULL && vd != NULL) - return (EBUSY); - - if (nspares == 1) { - newspares = NULL; - } else { - newspares = kmem_alloc((nspares - 1) * sizeof (void *), - KM_SLEEP); - for (i = 0, j = 0; i < nspares; i++) { - if (spares[i] != nv) - VERIFY(nvlist_dup(spares[i], - &newspares[j++], KM_SLEEP) == 0); - } - } - - VERIFY(nvlist_remove(sav->sav_config, ZPOOL_CONFIG_SPARES, - DATA_TYPE_NVLIST_ARRAY) == 0); - VERIFY(nvlist_add_nvlist_array(sav->sav_config, - ZPOOL_CONFIG_SPARES, newspares, nspares - 1) == 0); - for (i = 0; i < nspares - 1; i++) - nvlist_free(newspares[i]); - kmem_free(newspares, (nspares - 1) * sizeof (void *)); - - return (0); + return (NULL); } -/* - * Remove an l2cache vdev from the nvlist config. - */ -static int -spa_remove_l2cache(spa_aux_vdev_t *sav, uint64_t guid, nvlist_t **l2cache, - int nl2cache, vdev_t *vd) +static void +spa_vdev_remove_aux(nvlist_t *config, char *name, nvlist_t **dev, int count, + nvlist_t *dev_to_remove) { - nvlist_t *nv, **newl2cache; - int i, j; + nvlist_t **newdev = NULL; - nv = NULL; - for (i = 0; i < nl2cache; i++) { - uint64_t theguid; + if (count > 1) + newdev = kmem_alloc((count - 1) * sizeof (void *), KM_SLEEP); - VERIFY(nvlist_lookup_uint64(l2cache[i], - ZPOOL_CONFIG_GUID, &theguid) == 0); - if (theguid == guid) { - nv = l2cache[i]; - break; - } + for (int i = 0, j = 0; i < count; i++) { + if (dev[i] == dev_to_remove) + continue; + VERIFY(nvlist_dup(dev[i], &newdev[j++], KM_SLEEP) == 0); } - if (vd == NULL) { - for (i = 0; i < nl2cache; i++) { - if (sav->sav_vdevs[i]->vdev_guid == guid) { - vd = sav->sav_vdevs[i]; - break; - } - } - } + VERIFY(nvlist_remove(config, name, DATA_TYPE_NVLIST_ARRAY) == 0); + VERIFY(nvlist_add_nvlist_array(config, name, newdev, count - 1) == 0); - if (nv == NULL && vd == NULL) - return (ENOENT); + for (int i = 0; i < count - 1; i++) + nvlist_free(newdev[i]); - if (nv == NULL && vd != NULL) - return (ENOTSUP); - - if (nl2cache == 1) { - newl2cache = NULL; - } else { - newl2cache = kmem_alloc((nl2cache - 1) * sizeof (void *), - KM_SLEEP); - for (i = 0, j = 0; i < nl2cache; i++) { - if (l2cache[i] != nv) - VERIFY(nvlist_dup(l2cache[i], - &newl2cache[j++], KM_SLEEP) == 0); - } - } - - VERIFY(nvlist_remove(sav->sav_config, ZPOOL_CONFIG_L2CACHE, - DATA_TYPE_NVLIST_ARRAY) == 0); - VERIFY(nvlist_add_nvlist_array(sav->sav_config, - ZPOOL_CONFIG_L2CACHE, newl2cache, nl2cache - 1) == 0); - for (i = 0; i < nl2cache - 1; i++) - nvlist_free(newl2cache[i]); - kmem_free(newl2cache, (nl2cache - 1) * sizeof (void *)); - - return (0); + if (count > 1) + kmem_free(newdev, (count - 1) * sizeof (void *)); } /* @@ -3134,40 +3254,55 @@ int spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare) { vdev_t *vd; - nvlist_t **spares, **l2cache; + nvlist_t **spares, **l2cache, *nv; uint_t nspares, nl2cache; + uint64_t txg; int error = 0; - spa_config_enter(spa, RW_WRITER, FTAG); + txg = spa_vdev_enter(spa); - vd = spa_lookup_by_guid(spa, guid); + vd = spa_lookup_by_guid(spa, guid, B_FALSE); if (spa->spa_spares.sav_vdevs != NULL && - spa_spare_exists(guid, NULL) && nvlist_lookup_nvlist_array(spa->spa_spares.sav_config, - ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) { - if ((error = spa_remove_spares(&spa->spa_spares, guid, unspare, - spares, nspares, vd)) != 0) - goto out; - spa_load_spares(spa); - spa->spa_spares.sav_sync = B_TRUE; - goto out; - } - - if (spa->spa_l2cache.sav_vdevs != NULL && - spa_l2cache_exists(guid, NULL) && + ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0 && + (nv = spa_nvlist_lookup_by_guid(spares, nspares, guid)) != NULL) { + /* + * Only remove the hot spare if it's not currently in use + * in this pool. + */ + if (vd == NULL || unspare) { + spa_vdev_remove_aux(spa->spa_spares.sav_config, + ZPOOL_CONFIG_SPARES, spares, nspares, nv); + spa_load_spares(spa); + spa->spa_spares.sav_sync = B_TRUE; + } else { + error = EBUSY; + } + } else if (spa->spa_l2cache.sav_vdevs != NULL && nvlist_lookup_nvlist_array(spa->spa_l2cache.sav_config, - ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0) { - if ((error = spa_remove_l2cache(&spa->spa_l2cache, guid, - l2cache, nl2cache, vd)) != 0) - goto out; + ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0 && + (nv = spa_nvlist_lookup_by_guid(l2cache, nl2cache, guid)) != NULL) { + /* + * Cache devices can always be removed. + */ + spa_vdev_remove_aux(spa->spa_l2cache.sav_config, + ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache, nv); spa_load_l2cache(spa); spa->spa_l2cache.sav_sync = B_TRUE; + } else if (vd != NULL) { + /* + * Normal vdevs cannot be removed (yet). + */ + error = ENOTSUP; + } else { + /* + * There is no vdev of any kind with the specified guid. + */ + error = ENOENT; } -out: - spa_config_exit(spa, FTAG); - return (error); + return (spa_vdev_exit(spa, NULL, txg, error)); } /* @@ -3231,7 +3366,7 @@ spa_vdev_resilver_done(spa_t *spa) uint64_t guid; uint64_t pguid = 0; - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER); while ((vd = spa_vdev_resilver_done_hunt(spa->spa_root_vdev)) != NULL) { guid = vd->vdev_guid; @@ -3247,15 +3382,15 @@ spa_vdev_resilver_done(spa_t *spa) ASSERT(pvd->vdev_parent->vdev_children == 2); pguid = pvd->vdev_parent->vdev_child[1]->vdev_guid; } - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_CONFIG, FTAG); if (spa_vdev_detach(spa, guid, B_TRUE) != 0) return; if (pguid != 0 && spa_vdev_detach(spa, pguid, B_TRUE) != 0) return; - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER); } - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_CONFIG, FTAG); } /* @@ -3265,21 +3400,19 @@ spa_vdev_resilver_done(spa_t *spa) int spa_vdev_setpath(spa_t *spa, uint64_t guid, const char *newpath) { - vdev_t *rvd, *vd; + vdev_t *vd; uint64_t txg; - rvd = spa->spa_root_vdev; - txg = spa_vdev_enter(spa); - if ((vd = vdev_lookup_by_guid(rvd, guid)) == NULL) { + if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) { /* - * Determine if this is a reference to a hot spare or l2cache - * device. If it is, update the path as stored in their - * device list. + * Determine if this is a reference to a hot spare device. If + * it is, update the path manually as there is no associated + * vdev_t that can be synced to disk. */ - nvlist_t **spares, **l2cache; - uint_t i, nspares, nl2cache; + nvlist_t **spares; + uint_t i, nspares; if (spa->spa_spares.sav_config != NULL) { VERIFY(nvlist_lookup_nvlist_array( @@ -3300,25 +3433,6 @@ spa_vdev_setpath(spa_t *spa, uint64_t guid, const char *newpath) } } - if (spa->spa_l2cache.sav_config != NULL) { - VERIFY(nvlist_lookup_nvlist_array( - spa->spa_l2cache.sav_config, ZPOOL_CONFIG_L2CACHE, - &l2cache, &nl2cache) == 0); - for (i = 0; i < nl2cache; i++) { - uint64_t theguid; - VERIFY(nvlist_lookup_uint64(l2cache[i], - ZPOOL_CONFIG_GUID, &theguid) == 0); - if (theguid == guid) { - VERIFY(nvlist_add_string(l2cache[i], - ZPOOL_CONFIG_PATH, newpath) == 0); - spa_load_l2cache(spa); - spa->spa_l2cache.sav_sync = B_TRUE; - return (spa_vdev_exit(spa, NULL, txg, - 0)); - } - } - } - return (spa_vdev_exit(spa, NULL, txg, ENOENT)); } @@ -3339,404 +3453,36 @@ spa_vdev_setpath(spa_t *spa, uint64_t guid, const char *newpath) * ========================================================================== */ -static void -spa_scrub_io_done(zio_t *zio) -{ - spa_t *spa = zio->io_spa; - - arc_data_buf_free(zio->io_data, zio->io_size); - - mutex_enter(&spa->spa_scrub_lock); - if (zio->io_error && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { - vdev_t *vd = zio->io_vd ? zio->io_vd : spa->spa_root_vdev; - spa->spa_scrub_errors++; - mutex_enter(&vd->vdev_stat_lock); - vd->vdev_stat.vs_scrub_errors++; - mutex_exit(&vd->vdev_stat_lock); - } - - if (--spa->spa_scrub_inflight < spa->spa_scrub_maxinflight) - cv_broadcast(&spa->spa_scrub_io_cv); - - ASSERT(spa->spa_scrub_inflight >= 0); - - mutex_exit(&spa->spa_scrub_lock); -} - -static void -spa_scrub_io_start(spa_t *spa, blkptr_t *bp, int priority, int flags, - zbookmark_t *zb) -{ - size_t size = BP_GET_LSIZE(bp); - void *data; - - mutex_enter(&spa->spa_scrub_lock); - /* - * Do not give too much work to vdev(s). - */ - while (spa->spa_scrub_inflight >= spa->spa_scrub_maxinflight) { - cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock); - } - spa->spa_scrub_inflight++; - mutex_exit(&spa->spa_scrub_lock); - - data = arc_data_buf_alloc(size); - - if (zb->zb_level == -1 && BP_GET_TYPE(bp) != DMU_OT_OBJSET) - flags |= ZIO_FLAG_SPECULATIVE; /* intent log block */ - - flags |= ZIO_FLAG_SCRUB_THREAD | ZIO_FLAG_CANFAIL; - - zio_nowait(zio_read(NULL, spa, bp, data, size, - spa_scrub_io_done, NULL, priority, flags, zb)); -} - -/* ARGSUSED */ -static int -spa_scrub_cb(traverse_blk_cache_t *bc, spa_t *spa, void *a) -{ - blkptr_t *bp = &bc->bc_blkptr; - vdev_t *vd = spa->spa_root_vdev; - dva_t *dva = bp->blk_dva; - int needs_resilver = B_FALSE; - int d; - - if (bc->bc_errno) { - /* - * We can't scrub this block, but we can continue to scrub - * the rest of the pool. Note the error and move along. - */ - mutex_enter(&spa->spa_scrub_lock); - spa->spa_scrub_errors++; - mutex_exit(&spa->spa_scrub_lock); - - mutex_enter(&vd->vdev_stat_lock); - vd->vdev_stat.vs_scrub_errors++; - mutex_exit(&vd->vdev_stat_lock); - - return (ERESTART); - } - - ASSERT(bp->blk_birth < spa->spa_scrub_maxtxg); - - for (d = 0; d < BP_GET_NDVAS(bp); d++) { - vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[d])); - - ASSERT(vd != NULL); - - /* - * Keep track of how much data we've examined so that - * zpool(1M) status can make useful progress reports. - */ - mutex_enter(&vd->vdev_stat_lock); - vd->vdev_stat.vs_scrub_examined += DVA_GET_ASIZE(&dva[d]); - mutex_exit(&vd->vdev_stat_lock); - - if (spa->spa_scrub_type == POOL_SCRUB_RESILVER) { - if (DVA_GET_GANG(&dva[d])) { - /* - * Gang members may be spread across multiple - * vdevs, so the best we can do is look at the - * pool-wide DTL. - * XXX -- it would be better to change our - * allocation policy to ensure that this can't - * happen. - */ - vd = spa->spa_root_vdev; - } - if (vdev_dtl_contains(&vd->vdev_dtl_map, - bp->blk_birth, 1)) - needs_resilver = B_TRUE; - } - } - - if (spa->spa_scrub_type == POOL_SCRUB_EVERYTHING) - spa_scrub_io_start(spa, bp, ZIO_PRIORITY_SCRUB, - ZIO_FLAG_SCRUB, &bc->bc_bookmark); - else if (needs_resilver) - spa_scrub_io_start(spa, bp, ZIO_PRIORITY_RESILVER, - ZIO_FLAG_RESILVER, &bc->bc_bookmark); - - return (0); -} - -static void -spa_scrub_thread(spa_t *spa) -{ - callb_cpr_t cprinfo; - traverse_handle_t *th = spa->spa_scrub_th; - vdev_t *rvd = spa->spa_root_vdev; - pool_scrub_type_t scrub_type = spa->spa_scrub_type; - int error = 0; - boolean_t complete; - - CALLB_CPR_INIT(&cprinfo, &spa->spa_scrub_lock, callb_generic_cpr, FTAG); - - /* - * If we're restarting due to a snapshot create/delete, - * wait for that to complete. - */ - txg_wait_synced(spa_get_dsl(spa), 0); - - dprintf("start %s mintxg=%llu maxtxg=%llu\n", - scrub_type == POOL_SCRUB_RESILVER ? "resilver" : "scrub", - spa->spa_scrub_mintxg, spa->spa_scrub_maxtxg); - - spa_config_enter(spa, RW_WRITER, FTAG); - vdev_reopen(rvd); /* purge all vdev caches */ - vdev_config_dirty(rvd); /* rewrite all disk labels */ - vdev_scrub_stat_update(rvd, scrub_type, B_FALSE); - spa_config_exit(spa, FTAG); - - mutex_enter(&spa->spa_scrub_lock); - spa->spa_scrub_errors = 0; - spa->spa_scrub_active = 1; - ASSERT(spa->spa_scrub_inflight == 0); - - while (!spa->spa_scrub_stop) { - CALLB_CPR_SAFE_BEGIN(&cprinfo); - while (spa->spa_scrub_suspended) { - spa->spa_scrub_active = 0; - cv_broadcast(&spa->spa_scrub_cv); - cv_wait(&spa->spa_scrub_cv, &spa->spa_scrub_lock); - spa->spa_scrub_active = 1; - } - CALLB_CPR_SAFE_END(&cprinfo, &spa->spa_scrub_lock); - - if (spa->spa_scrub_restart_txg != 0) - break; - - mutex_exit(&spa->spa_scrub_lock); - error = traverse_more(th); - mutex_enter(&spa->spa_scrub_lock); - if (error != EAGAIN) - break; - } - - while (spa->spa_scrub_inflight) - cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock); - - spa->spa_scrub_active = 0; - cv_broadcast(&spa->spa_scrub_cv); - - mutex_exit(&spa->spa_scrub_lock); - - spa_config_enter(spa, RW_WRITER, FTAG); - - mutex_enter(&spa->spa_scrub_lock); - - /* - * Note: we check spa_scrub_restart_txg under both spa_scrub_lock - * AND the spa config lock to synchronize with any config changes - * that revise the DTLs under spa_vdev_enter() / spa_vdev_exit(). - */ - if (spa->spa_scrub_restart_txg != 0) - error = ERESTART; - - if (spa->spa_scrub_stop) - error = EINTR; - - /* - * Even if there were uncorrectable errors, we consider the scrub - * completed. The downside is that if there is a transient error during - * a resilver, we won't resilver the data properly to the target. But - * if the damage is permanent (more likely) we will resilver forever, - * which isn't really acceptable. Since there is enough information for - * the user to know what has failed and why, this seems like a more - * tractable approach. - */ - complete = (error == 0); - - dprintf("end %s to maxtxg=%llu %s, traverse=%d, %llu errors, stop=%u\n", - scrub_type == POOL_SCRUB_RESILVER ? "resilver" : "scrub", - spa->spa_scrub_maxtxg, complete ? "done" : "FAILED", - error, spa->spa_scrub_errors, spa->spa_scrub_stop); - - mutex_exit(&spa->spa_scrub_lock); - - /* - * If the scrub/resilver completed, update all DTLs to reflect this. - * Whether it succeeded or not, vacate all temporary scrub DTLs. - */ - vdev_dtl_reassess(rvd, spa_last_synced_txg(spa) + 1, - complete ? spa->spa_scrub_maxtxg : 0, B_TRUE); - vdev_scrub_stat_update(rvd, POOL_SCRUB_NONE, complete); - spa_errlog_rotate(spa); - - if (scrub_type == POOL_SCRUB_RESILVER && complete) - spa_event_notify(spa, NULL, ESC_ZFS_RESILVER_FINISH); - - spa_config_exit(spa, FTAG); - - mutex_enter(&spa->spa_scrub_lock); - - /* - * We may have finished replacing a device. - * Let the async thread assess this and handle the detach. - */ - spa_async_request(spa, SPA_ASYNC_RESILVER_DONE); - - /* - * If we were told to restart, our final act is to start a new scrub. - */ - if (error == ERESTART) - spa_async_request(spa, scrub_type == POOL_SCRUB_RESILVER ? - SPA_ASYNC_RESILVER : SPA_ASYNC_SCRUB); - - spa->spa_scrub_type = POOL_SCRUB_NONE; - spa->spa_scrub_active = 0; - spa->spa_scrub_thread = NULL; - cv_broadcast(&spa->spa_scrub_cv); - CALLB_CPR_EXIT(&cprinfo); /* drops &spa->spa_scrub_lock */ - thread_exit(); -} - -void -spa_scrub_suspend(spa_t *spa) -{ - mutex_enter(&spa->spa_scrub_lock); - spa->spa_scrub_suspended++; - while (spa->spa_scrub_active) { - cv_broadcast(&spa->spa_scrub_cv); - cv_wait(&spa->spa_scrub_cv, &spa->spa_scrub_lock); - } - while (spa->spa_scrub_inflight) - cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock); - mutex_exit(&spa->spa_scrub_lock); -} - -void -spa_scrub_resume(spa_t *spa) -{ - mutex_enter(&spa->spa_scrub_lock); - ASSERT(spa->spa_scrub_suspended != 0); - if (--spa->spa_scrub_suspended == 0) - cv_broadcast(&spa->spa_scrub_cv); - mutex_exit(&spa->spa_scrub_lock); -} - -void -spa_scrub_restart(spa_t *spa, uint64_t txg) -{ - /* - * Something happened (e.g. snapshot create/delete) that means - * we must restart any in-progress scrubs. The itinerary will - * fix this properly. - */ - mutex_enter(&spa->spa_scrub_lock); - spa->spa_scrub_restart_txg = txg; - mutex_exit(&spa->spa_scrub_lock); -} - int -spa_scrub(spa_t *spa, pool_scrub_type_t type, boolean_t force) +spa_scrub(spa_t *spa, pool_scrub_type_t type) { - space_seg_t *ss; - uint64_t mintxg, maxtxg; - vdev_t *rvd = spa->spa_root_vdev; - - ASSERT(MUTEX_HELD(&spa_namespace_lock)); - ASSERT(!spa_config_held(spa, RW_WRITER)); + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0); if ((uint_t)type >= POOL_SCRUB_TYPES) return (ENOTSUP); - mutex_enter(&spa->spa_scrub_lock); - /* - * If there's a scrub or resilver already in progress, stop it. + * If a resilver was requested, but there is no DTL on a + * writeable leaf device, we have nothing to do. */ - while (spa->spa_scrub_thread != NULL) { - /* - * Don't stop a resilver unless forced. - */ - if (spa->spa_scrub_type == POOL_SCRUB_RESILVER && !force) { - mutex_exit(&spa->spa_scrub_lock); - return (EBUSY); - } - spa->spa_scrub_stop = 1; - cv_broadcast(&spa->spa_scrub_cv); - cv_wait(&spa->spa_scrub_cv, &spa->spa_scrub_lock); - } - - /* - * Terminate the previous traverse. - */ - if (spa->spa_scrub_th != NULL) { - traverse_fini(spa->spa_scrub_th); - spa->spa_scrub_th = NULL; - } - - if (rvd == NULL) { - ASSERT(spa->spa_scrub_stop == 0); - ASSERT(spa->spa_scrub_type == type); - ASSERT(spa->spa_scrub_restart_txg == 0); - mutex_exit(&spa->spa_scrub_lock); + if (type == POOL_SCRUB_RESILVER && + !vdev_resilver_needed(spa->spa_root_vdev, NULL, NULL)) { + spa_async_request(spa, SPA_ASYNC_RESILVER_DONE); return (0); } - mintxg = TXG_INITIAL - 1; - maxtxg = spa_last_synced_txg(spa) + 1; + if (type == POOL_SCRUB_EVERYTHING && + spa->spa_dsl_pool->dp_scrub_func != SCRUB_FUNC_NONE && + spa->spa_dsl_pool->dp_scrub_isresilver) + return (EBUSY); - mutex_enter(&rvd->vdev_dtl_lock); - - if (rvd->vdev_dtl_map.sm_space == 0) { - /* - * The pool-wide DTL is empty. - * If this is a resilver, there's nothing to do except - * check whether any in-progress replacements have completed. - */ - if (type == POOL_SCRUB_RESILVER) { - type = POOL_SCRUB_NONE; - spa_async_request(spa, SPA_ASYNC_RESILVER_DONE); - } + if (type == POOL_SCRUB_EVERYTHING || type == POOL_SCRUB_RESILVER) { + return (dsl_pool_scrub_clean(spa->spa_dsl_pool)); + } else if (type == POOL_SCRUB_NONE) { + return (dsl_pool_scrub_cancel(spa->spa_dsl_pool)); } else { - /* - * The pool-wide DTL is non-empty. - * If this is a normal scrub, upgrade to a resilver instead. - */ - if (type == POOL_SCRUB_EVERYTHING) - type = POOL_SCRUB_RESILVER; + return (EINVAL); } - - if (type == POOL_SCRUB_RESILVER) { - /* - * Determine the resilvering boundaries. - * - * Note: (mintxg, maxtxg) is an open interval, - * i.e. mintxg and maxtxg themselves are not included. - * - * Note: for maxtxg, we MIN with spa_last_synced_txg(spa) + 1 - * so we don't claim to resilver a txg that's still changing. - */ - ss = avl_first(&rvd->vdev_dtl_map.sm_root); - mintxg = ss->ss_start - 1; - ss = avl_last(&rvd->vdev_dtl_map.sm_root); - maxtxg = MIN(ss->ss_end, maxtxg); - - spa_event_notify(spa, NULL, ESC_ZFS_RESILVER_START); - } - - mutex_exit(&rvd->vdev_dtl_lock); - - spa->spa_scrub_stop = 0; - spa->spa_scrub_type = type; - spa->spa_scrub_restart_txg = 0; - - if (type != POOL_SCRUB_NONE) { - spa->spa_scrub_mintxg = mintxg; - spa->spa_scrub_maxtxg = maxtxg; - spa->spa_scrub_th = traverse_init(spa, spa_scrub_cb, NULL, - ADVANCE_PRE | ADVANCE_PRUNE | ADVANCE_ZIL, - ZIO_FLAG_CANFAIL); - traverse_add_pool(spa->spa_scrub_th, mintxg, maxtxg); - spa->spa_scrub_thread = thread_create(NULL, 0, - spa_scrub_thread, spa, 0, &p0, TS_RUN, minclsyspri); - } - - mutex_exit(&spa->spa_scrub_lock); - - return (0); } /* @@ -3748,27 +3494,33 @@ spa_scrub(spa_t *spa, pool_scrub_type_t type, boolean_t force) static void spa_async_remove(spa_t *spa, vdev_t *vd) { - vdev_t *tvd; - int c; - - for (c = 0; c < vd->vdev_children; c++) { - tvd = vd->vdev_child[c]; - if (tvd->vdev_remove_wanted) { - tvd->vdev_remove_wanted = 0; - vdev_set_state(tvd, B_FALSE, VDEV_STATE_REMOVED, - VDEV_AUX_NONE); - vdev_clear(spa, tvd, B_TRUE); - vdev_config_dirty(tvd->vdev_top); - } - spa_async_remove(spa, tvd); + if (vd->vdev_remove_wanted) { + vd->vdev_remove_wanted = 0; + vdev_set_state(vd, B_FALSE, VDEV_STATE_REMOVED, VDEV_AUX_NONE); + vdev_clear(spa, vd); + vdev_state_dirty(vd->vdev_top); } + + for (int c = 0; c < vd->vdev_children; c++) + spa_async_remove(spa, vd->vdev_child[c]); +} + +static void +spa_async_probe(spa_t *spa, vdev_t *vd) +{ + if (vd->vdev_probe_wanted) { + vd->vdev_probe_wanted = 0; + vdev_reopen(vd); /* vdev_open() does the actual probe */ + } + + for (int c = 0; c < vd->vdev_children; c++) + spa_async_probe(spa, vd->vdev_child[c]); } static void spa_async_thread(spa_t *spa) { int tasks; - uint64_t txg; ASSERT(spa->spa_sync_on); @@ -3788,17 +3540,24 @@ spa_async_thread(spa_t *spa) /* * See if any devices need to be marked REMOVED. - * - * XXX - We avoid doing this when we are in - * I/O failure state since spa_vdev_enter() grabs - * the namespace lock and would not be able to obtain - * the writer config lock. */ - if (tasks & SPA_ASYNC_REMOVE && - spa_state(spa) != POOL_STATE_IO_FAILURE) { - txg = spa_vdev_enter(spa); + if (tasks & SPA_ASYNC_REMOVE) { + spa_vdev_state_enter(spa); spa_async_remove(spa, spa->spa_root_vdev); - (void) spa_vdev_exit(spa, NULL, txg, 0); + for (int i = 0; i < spa->spa_l2cache.sav_count; i++) + spa_async_remove(spa, spa->spa_l2cache.sav_vdevs[i]); + for (int i = 0; i < spa->spa_spares.sav_count; i++) + spa_async_remove(spa, spa->spa_spares.sav_vdevs[i]); + (void) spa_vdev_state_exit(spa, NULL, 0); + } + + /* + * See if any devices need to be probed. + */ + if (tasks & SPA_ASYNC_PROBE) { + spa_vdev_state_enter(spa); + spa_async_probe(spa, spa->spa_root_vdev); + (void) spa_vdev_state_exit(spa, NULL, 0); } /* @@ -3807,26 +3566,11 @@ spa_async_thread(spa_t *spa) if (tasks & SPA_ASYNC_RESILVER_DONE) spa_vdev_resilver_done(spa); - /* - * Kick off a scrub. When starting a RESILVER scrub (or an EVERYTHING - * scrub which can become a resilver), we need to hold - * spa_namespace_lock() because the sysevent we post via - * spa_event_notify() needs to get the name of the pool. - */ - if (tasks & SPA_ASYNC_SCRUB) { - mutex_enter(&spa_namespace_lock); - VERIFY(spa_scrub(spa, POOL_SCRUB_EVERYTHING, B_TRUE) == 0); - mutex_exit(&spa_namespace_lock); - } - /* * Kick off a resilver. */ - if (tasks & SPA_ASYNC_RESILVER) { - mutex_enter(&spa_namespace_lock); - VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0); - mutex_exit(&spa_namespace_lock); - } + if (tasks & SPA_ASYNC_RESILVER) + VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER) == 0); /* * Let the world know that we're done. @@ -3894,10 +3638,13 @@ spa_sync_deferred_frees(spa_t *spa, uint64_t txg) int error; uint8_t c = 1; - zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CONFIG_HELD); + zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL); - while (bplist_iterate(bpl, &itor, &blk) == 0) - zio_nowait(zio_free(zio, spa, txg, &blk, NULL, NULL)); + while (bplist_iterate(bpl, &itor, &blk) == 0) { + ASSERT(blk.blk_birth < txg); + zio_nowait(zio_free(zio, spa, txg, &blk, NULL, NULL, + ZIO_FLAG_MUSTSUCCEED)); + } error = zio_wait(zio); ASSERT3U(error, ==, 0); @@ -3917,19 +3664,27 @@ static void spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx) { char *packed = NULL; + size_t bufsize; size_t nvsize = 0; dmu_buf_t *db; VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_XDR) == 0); - packed = kmem_alloc(nvsize, KM_SLEEP); + /* + * Write full (SPA_CONFIG_BLOCKSIZE) blocks of configuration + * information. This avoids the dbuf_will_dirty() path and + * saves us a pre-read to get data we don't actually care about. + */ + bufsize = P2ROUNDUP(nvsize, SPA_CONFIG_BLOCKSIZE); + packed = kmem_alloc(bufsize, KM_SLEEP); VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR, KM_SLEEP) == 0); + bzero(packed + nvsize, bufsize - nvsize); - dmu_write(spa->spa_meta_objset, obj, 0, nvsize, packed, tx); + dmu_write(spa->spa_meta_objset, obj, 0, bufsize, packed, tx); - kmem_free(packed, nvsize); + kmem_free(packed, bufsize); VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db)); dmu_buf_will_dirty(db, tx); @@ -3988,10 +3743,15 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx) { nvlist_t *config; - if (list_is_empty(&spa->spa_dirty_list)) + if (list_is_empty(&spa->spa_config_dirty_list)) return; - config = spa_config_generate(spa, NULL, dmu_tx_get_txg(tx), B_FALSE); + spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); + + config = spa_config_generate(spa, spa->spa_root_vdev, + dmu_tx_get_txg(tx), B_FALSE); + + spa_config_exit(spa, SCL_STATE, FTAG); if (spa->spa_config_syncing) nvlist_free(spa->spa_config_syncing); @@ -4011,10 +3771,13 @@ spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) nvlist_t *nvp = arg2; nvpair_t *elem; uint64_t intval; - char *strval, *slash; + char *strval; zpool_prop_t prop; const char *propname; zprop_type_t proptype; + spa_config_dirent_t *dp; + + mutex_enter(&spa->spa_props_lock); elem = NULL; while ((elem = nvlist_next_nvpair(nvp, elem))) { @@ -4050,47 +3813,23 @@ spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) * udpated. */ VERIFY(nvpair_value_string(elem, &strval) == 0); - if (spa->spa_config_dir) - spa_strfree(spa->spa_config_dir); - if (spa->spa_config_file) - spa_strfree(spa->spa_config_file); - if (strval[0] == '\0') { - spa->spa_config_dir = NULL; - spa->spa_config_file = NULL; - } else if (strcmp(strval, "none") == 0) { - spa->spa_config_dir = spa_strdup(strval); - spa->spa_config_file = NULL; - } else { - /* - * If the cachefile is in the root directory, - * we will end up with an empty string for - * spa_config_dir. This value is only ever - * used when concatenated with '/', so an empty - * string still behaves correctly and keeps the - * rest of the code simple. - */ - slash = strrchr(strval, '/'); - ASSERT(slash != NULL); - *slash = '\0'; - if (strcmp(strval, spa_config_dir) == 0 && - strcmp(slash + 1, ZPOOL_CACHE_FILE) == 0) { - spa->spa_config_dir = NULL; - spa->spa_config_file = NULL; - } else { - spa->spa_config_dir = - spa_strdup(strval); - spa->spa_config_file = - spa_strdup(slash + 1); - } - } + dp = kmem_alloc(sizeof (spa_config_dirent_t), KM_SLEEP); + + if (strval[0] == '\0') + dp->scd_path = spa_strdup(spa_config_path); + else if (strcmp(strval, "none") == 0) + dp->scd_path = NULL; + else + dp->scd_path = spa_strdup(strval); + + list_insert_head(&spa->spa_config_list, dp); spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE); break; default: /* * Set pool property values in the poolprops mos object. */ - mutex_enter(&spa->spa_props_lock); if (spa->spa_pool_props_object == 0) { objset_t *mos = spa->spa_meta_objset; @@ -4103,7 +3842,6 @@ spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 8, 1, &spa->spa_pool_props_object, tx) == 0); } - mutex_exit(&spa->spa_props_lock); /* normalize the property name */ propname = zpool_prop_to_name(prop); @@ -4151,9 +3889,11 @@ spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) tx->tx_txg != TXG_INITIAL) { spa_history_internal_log(LOG_POOL_PROPSET, spa, tx, cr, "%s %lld %s", - nvpair_name(elem), intval, spa->spa_name); + nvpair_name(elem), intval, spa_name(spa)); } } + + mutex_exit(&spa->spa_props_lock); } /* @@ -4168,19 +3908,29 @@ spa_sync(spa_t *spa, uint64_t txg) bplist_t *bpl = &spa->spa_sync_bplist; vdev_t *rvd = spa->spa_root_vdev; vdev_t *vd; - vdev_t *svd[SPA_DVAS_PER_BP]; - int svdcount = 0; dmu_tx_t *tx; int dirty_vdevs; + int error; /* * Lock out configuration changes. */ - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER); spa->spa_syncing_txg = txg; spa->spa_sync_pass = 0; + /* + * If there are any pending vdev state changes, convert them + * into config changes that go out with this transaction group. + */ + spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); + while ((vd = list_head(&spa->spa_state_dirty_list)) != NULL) { + vdev_state_clean(vd); + vdev_config_dirty(vd); + } + spa_config_exit(spa, SCL_STATE, FTAG); + VERIFY(0 == bplist_open(bpl, mos, spa->spa_sync_bplist_obj)); tx = dmu_tx_create_assigned(dp, txg); @@ -4206,6 +3956,19 @@ spa_sync(spa_t *spa, uint64_t txg) } } + if (spa->spa_ubsync.ub_version < SPA_VERSION_ORIGIN && + spa->spa_uberblock.ub_version >= SPA_VERSION_ORIGIN) { + dsl_pool_create_origin(dp, tx); + + /* Keeping the origin open increases spa_minref */ + spa->spa_minref += 3; + } + + if (spa->spa_ubsync.ub_version < SPA_VERSION_NEXT_CLONES && + spa->spa_uberblock.ub_version >= SPA_VERSION_NEXT_CLONES) { + dsl_pool_upgrade_clones(dp, tx); + } + /* * If anything has changed in this txg, push the deferred frees * from the previous txg. If not, leave them alone so that we @@ -4249,34 +4012,50 @@ spa_sync(spa_t *spa, uint64_t txg) * * If there are no dirty vdevs, we sync the uberblock to a few * random top-level vdevs that are known to be visible in the - * config cache (see spa_vdev_add() for details). If there *are* - * dirty vdevs -- or if the sync to our random subset fails -- - * then sync the uberblock to all vdevs. + * config cache (see spa_vdev_add() for a complete description). + * If there *are* dirty vdevs, sync the uberblock to all vdevs. */ - if (list_is_empty(&spa->spa_dirty_list)) { - int children = rvd->vdev_children; - int c0 = spa_get_random(children); - int c; + for (;;) { + /* + * We hold SCL_STATE to prevent vdev open/close/etc. + * while we're attempting to write the vdev labels. + */ + spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); - for (c = 0; c < children; c++) { - vd = rvd->vdev_child[(c0 + c) % children]; - if (vd->vdev_ms_array == 0 || vd->vdev_islog) - continue; - svd[svdcount++] = vd; - if (svdcount == SPA_DVAS_PER_BP) - break; + if (list_is_empty(&spa->spa_config_dirty_list)) { + vdev_t *svd[SPA_DVAS_PER_BP]; + int svdcount = 0; + int children = rvd->vdev_children; + int c0 = spa_get_random(children); + int c; + + for (c = 0; c < children; c++) { + vd = rvd->vdev_child[(c0 + c) % children]; + if (vd->vdev_ms_array == 0 || vd->vdev_islog) + continue; + svd[svdcount++] = vd; + if (svdcount == SPA_DVAS_PER_BP) + break; + } + error = vdev_config_sync(svd, svdcount, txg); + } else { + error = vdev_config_sync(rvd->vdev_child, + rvd->vdev_children, txg); } - } - if (svdcount == 0 || vdev_config_sync(svd, svdcount, txg) != 0) - VERIFY3U(vdev_config_sync(rvd->vdev_child, - rvd->vdev_children, txg), ==, 0); + spa_config_exit(spa, SCL_STATE, FTAG); + + if (error == 0) + break; + zio_suspend(spa, NULL); + zio_resume_wait(spa); + } dmu_tx_commit(tx); /* * Clear the dirty config list. */ - while ((vd = list_head(&spa->spa_dirty_list)) != NULL) + while ((vd = list_head(&spa->spa_config_dirty_list)) != NULL) vdev_config_clean(vd); /* @@ -4289,20 +4068,7 @@ spa_sync(spa_t *spa, uint64_t txg) spa->spa_config_syncing = NULL; } - /* - * Make a stable copy of the fully synced uberblock. - * We use this as the root for pool traversals. - */ - spa->spa_traverse_wanted = 1; /* tells traverse_more() to stop */ - - spa_scrub_suspend(spa); /* stop scrubbing and finish I/Os */ - - rw_enter(&spa->spa_traverse_lock, RW_WRITER); - spa->spa_traverse_wanted = 0; spa->spa_ubsync = spa->spa_uberblock; - rw_exit(&spa->spa_traverse_lock); - - spa_scrub_resume(spa); /* resume scrub with new ubsync */ /* * Clean up the ZIL records for the synced txg. @@ -4324,7 +4090,7 @@ spa_sync(spa_t *spa, uint64_t txg) ASSERT(txg_list_empty(&spa->spa_vdev_txg_list, txg)); ASSERT(bpl->bpl_queue == NULL); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_CONFIG, FTAG); /* * If any async tasks have been requested, kick them off. @@ -4343,7 +4109,7 @@ spa_sync_allpools(void) spa_t *spa = NULL; mutex_enter(&spa_namespace_lock); while ((spa = spa_next(spa)) != NULL) { - if (spa_state(spa) != POOL_STATE_ACTIVE) + if (spa_state(spa) != POOL_STATE_ACTIVE || spa_suspended(spa)) continue; spa_open_ref(spa, FTAG); mutex_exit(&spa_namespace_lock); @@ -4383,7 +4149,6 @@ spa_evict_all(void) mutex_exit(&spa_namespace_lock); spa_async_suspend(spa); mutex_enter(&spa_namespace_lock); - VERIFY(spa_scrub(spa, POOL_SCRUB_NONE, B_TRUE) == 0); spa_close(spa, FTAG); if (spa->spa_state != POOL_STATE_UNINITIALIZED) { @@ -4396,15 +4161,29 @@ spa_evict_all(void) } vdev_t * -spa_lookup_by_guid(spa_t *spa, uint64_t guid) +spa_lookup_by_guid(spa_t *spa, uint64_t guid, boolean_t l2cache) { - return (vdev_lookup_by_guid(spa->spa_root_vdev, guid)); + vdev_t *vd; + int i; + + if ((vd = vdev_lookup_by_guid(spa->spa_root_vdev, guid)) != NULL) + return (vd); + + if (l2cache) { + for (i = 0; i < spa->spa_l2cache.sav_count; i++) { + vd = spa->spa_l2cache.sav_vdevs[i]; + if (vd->vdev_guid == guid) + return (vd); + } + } + + return (NULL); } void spa_upgrade(spa_t *spa, uint64_t version) { - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); /* * This should only be called for a non-faulted pool, and since a @@ -4417,7 +4196,7 @@ spa_upgrade(spa_t *spa, uint64_t version) spa->spa_uberblock.ub_version = version; vdev_config_dirty(spa->spa_root_vdev); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); txg_wait_synced(spa_get_dsl(spa), 0); } @@ -4442,6 +4221,27 @@ spa_has_spare(spa_t *spa, uint64_t guid) return (B_FALSE); } +/* + * Check if a pool has an active shared spare device. + * Note: reference count of an active spare is 2, as a spare and as a replace + */ +static boolean_t +spa_has_active_shared_spare(spa_t *spa) +{ + int i, refcnt; + uint64_t pool; + spa_aux_vdev_t *sav = &spa->spa_spares; + + for (i = 0; i < sav->sav_count; i++) { + if (spa_spare_exists(sav->sav_vdevs[i]->vdev_guid, &pool, + &refcnt) && pool != 0ULL && pool == spa_guid(spa) && + refcnt > 2) + return (B_TRUE); + } + + return (B_FALSE); +} + /* * Post a sysevent corresponding to the given event. The 'name' must be one of * the event definitions in sys/sysevent/eventdefs.h. The payload will be diff --git a/zfs/lib/libzpool/spa_boot.c b/zfs/lib/libzpool/spa_boot.c index 1107b0298..49e9e5019 100644 --- a/zfs/lib/libzpool/spa_boot.c +++ b/zfs/lib/libzpool/spa_boot.c @@ -24,175 +24,24 @@ * Use is subject to license terms. */ -#pragma ident "@(#)spa_boot.c 1.1 08/04/09 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include char * -spa_get_bootfs() +spa_get_bootprop(char *propname) { - char *zfs_bp; + char *value; if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), - DDI_PROP_DONTPASS, "zfs-bootfs", &zfs_bp) != - DDI_SUCCESS) + DDI_PROP_DONTPASS, propname, &value) != DDI_SUCCESS) return (NULL); - return (zfs_bp); + return (value); } void -spa_free_bootfs(char *bootfs) +spa_free_bootprop(char *value) { - ddi_prop_free(bootfs); -} - -/* - * Calculate how many device pathnames are in devpath_list. - * The devpath_list could look like this: - * - * "/pci@1f,0/ide@d/disk@0,0:a /pci@1f,o/ide@d/disk@2,0:a" - */ -static int -spa_count_devpath(char *devpath_list) -{ - int numpath; - char *tmp_path, *blank; - - numpath = 0; - tmp_path = devpath_list; - - /* skip leading blanks */ - while (*tmp_path == ' ') - tmp_path++; - - while ((blank = strchr(tmp_path, ' ')) != NULL) { - - numpath++; - /* skip contiguous blanks */ - while (*blank == ' ') - blank++; - tmp_path = blank; - } - - if (strlen(tmp_path) > 0) - numpath++; - - return (numpath); -} - -/* - * Only allow booting the device if it has the same vdev information as - * the most recently updated vdev (highest txg) and is in a valid state. - * - * GRUB passes online/active device path names, e.g. - * "/pci@1f,0/ide@d/disk@0,0:a /pci@1f,o/ide@d/disk@2,0:a" - * to the kernel. The best vdev should have the same matching online/active - * list as what GRUB passes in. - */ -static int -spa_check_devstate(char *devpath_list, char *dev, nvlist_t *conf) -{ - nvlist_t *nvtop, **child; - uint_t label_path, grub_path, c, children; - char *type; - - VERIFY(nvlist_lookup_nvlist(conf, ZPOOL_CONFIG_VDEV_TREE, - &nvtop) == 0); - VERIFY(nvlist_lookup_string(nvtop, ZPOOL_CONFIG_TYPE, &type) == 0); - - if (strcmp(type, VDEV_TYPE_DISK) == 0) - return (spa_rootdev_validate(nvtop)? 0 : EINVAL); - - ASSERT(strcmp(type, VDEV_TYPE_MIRROR) == 0); - - VERIFY(nvlist_lookup_nvlist_array(nvtop, ZPOOL_CONFIG_CHILDREN, - &child, &children) == 0); - - /* - * Check if the devpath_list is the same as the path list in conf. - * If these two lists are different, then the booting device is not an - * up-to-date device that can be booted. - */ - label_path = 0; - for (c = 0; c < children; c++) { - char *physpath; - - if (nvlist_lookup_string(child[c], ZPOOL_CONFIG_PHYS_PATH, - &physpath) != 0) - return (EINVAL); - - if (spa_rootdev_validate(child[c])) { - if (strstr(devpath_list, physpath) == NULL) - return (EINVAL); - label_path++; - } else { - char *blank; - - if (blank = strchr(dev, ' ')) - *blank = '\0'; - if (strcmp(physpath, dev) == 0) - return (EINVAL); - if (blank) - *blank = ' '; - } - } - - grub_path = spa_count_devpath(devpath_list); - - if (label_path != grub_path) - return (EINVAL); - - return (0); -} - -/* - * Given a list of vdev physpath names, pick the vdev with the most recent txg, - * and return the point of the device's physpath in the list and the device's - * label configuration. The content of the label would be the most recent - * updated information. - */ -int -spa_get_rootconf(char *devpath_list, char **bestdev, nvlist_t **bestconf) -{ - nvlist_t *conf = NULL; - char *dev = NULL; - uint64_t txg = 0; - char *devpath, *blank; - - devpath = devpath_list; - dev = devpath; - - while (devpath[0] == ' ') - devpath++; - - while ((blank = strchr(devpath, ' ')) != NULL) { - *blank = '\0'; - spa_check_rootconf(devpath, &dev, &conf, &txg); - *blank = ' '; - - while (*blank == ' ') - blank++; - devpath = blank; - } - - /* for the only or the last devpath in the devpath_list */ - if (strlen(devpath) > 0) - spa_check_rootconf(devpath, &dev, &conf, &txg); - - if (conf == NULL) - return (EINVAL); - - /* - * dev/conf is the vdev with the most recent txg. - * Check if the device is in a bootable state. - * dev may have a trailing blank since it points to a string - * in the devpath_list. - */ - if (spa_check_devstate(devpath_list, dev, conf) != 0) - return (EINVAL); - - *bestdev = dev; - *bestconf = conf; - return (0); + ddi_prop_free(value); } diff --git a/zfs/lib/libzpool/spa_config.c b/zfs/lib/libzpool/spa_config.c index c22e5e89d..ee425a916 100644 --- a/zfs/lib/libzpool/spa_config.c +++ b/zfs/lib/libzpool/spa_config.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)spa_config.c 1.15 08/04/01 SMI" - #include #include #include @@ -63,7 +61,7 @@ static uint64_t spa_config_generation = 1; * This can be overridden in userland to preserve an alternate namespace for * userland pools when doing testing. */ -const char *spa_config_dir = ZPOOL_CACHE_DIR; +const char *spa_config_path = ZPOOL_CACHE; /* * Called when the module is first loaded, this routine loads the configuration @@ -77,17 +75,22 @@ spa_config_load(void) nvlist_t *nvlist, *child; nvpair_t *nvpair; spa_t *spa; - char pathname[128]; + char *pathname; struct _buf *file; uint64_t fsize; /* * Open the configuration file. */ - (void) snprintf(pathname, sizeof (pathname), "%s%s/%s", - (rootdir != NULL) ? "./" : "", spa_config_dir, ZPOOL_CACHE_FILE); + pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP); + + (void) snprintf(pathname, MAXPATHLEN, "%s%s", + (rootdir != NULL) ? "./" : "", spa_config_path); file = kobj_open_file(pathname); + + kmem_free(pathname, MAXPATHLEN); + if (file == (struct _buf *)-1) return; @@ -142,120 +145,32 @@ out: kobj_close_file(file); } -/* - * This function is called when destroying or exporting a pool. It walks the - * list of active pools, and searches for any that match the given cache file. - * If there is only one cachefile, then the file is removed immediately, - * because we won't see the pool when iterating in spa_config_sync(). - */ -void -spa_config_check(const char *dir, const char *file) -{ - size_t count = 0; - char pathname[128]; - spa_t *spa; - - if (dir != NULL && strcmp(dir, "none") == 0) - return; - - ASSERT(MUTEX_HELD(&spa_namespace_lock)); - spa = NULL; - while ((spa = spa_next(spa)) != NULL) { - if (dir == NULL) { - if (spa->spa_config_dir == NULL) - count++; - } else { - if (spa->spa_config_dir && - strcmp(spa->spa_config_dir, dir) == 0 && - strcmp(spa->spa_config_file, file) == 0) - count++; - } - } - - if (count == 1) { - if (dir == NULL) { - dir = spa_config_dir; - file = ZPOOL_CACHE_FILE; - } - - (void) snprintf(pathname, sizeof (pathname), - "%s/%s", dir, file); - (void) vn_remove(pathname, UIO_SYSSPACE, RMFILE); - } -} - -typedef struct spa_config_entry { - list_t sc_link; - const char *sc_dir; - const char *sc_file; - nvlist_t *sc_nvl; -} spa_config_entry_t; - static void -spa_config_entry_add(list_t *listp, spa_t *spa) +spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) { - spa_config_entry_t *entry; - const char *dir, *file; - - mutex_enter(&spa->spa_config_cache_lock); - if (!spa->spa_config || !spa->spa_name) { - mutex_exit(&spa->spa_config_cache_lock); - return; - } - - if (spa->spa_config_dir) { - dir = spa->spa_config_dir; - file = spa->spa_config_file; - } else { - dir = spa_config_dir; - file = ZPOOL_CACHE_FILE; - } - - if (strcmp(dir, "none") == 0) { - mutex_exit(&spa->spa_config_cache_lock); - return; - } - - for (entry = list_head(listp); entry != NULL; - entry = list_next(listp, entry)) { - if (strcmp(entry->sc_dir, dir) == 0 && - strcmp(entry->sc_file, file) == 0) - break; - } - - if (entry == NULL) { - entry = kmem_alloc(sizeof (spa_config_entry_t), KM_SLEEP); - entry->sc_dir = dir; - entry->sc_file = file; - VERIFY(nvlist_alloc(&entry->sc_nvl, NV_UNIQUE_NAME, - KM_SLEEP) == 0); - list_insert_tail(listp, entry); - } - - VERIFY(nvlist_add_nvlist(entry->sc_nvl, spa->spa_name, - spa->spa_config) == 0); - mutex_exit(&spa->spa_config_cache_lock); -} - -static void -spa_config_entry_write(spa_config_entry_t *entry) -{ - nvlist_t *config = entry->sc_nvl; size_t buflen; char *buf; vnode_t *vp; int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX; - char pathname[128]; - char pathname2[128]; + char *temp; + + /* + * If the nvlist is empty (NULL), then remove the old cachefile. + */ + if (nvl == NULL) { + (void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE); + return; + } /* * Pack the configuration into a buffer. */ - VERIFY(nvlist_size(config, &buflen, NV_ENCODE_XDR) == 0); + VERIFY(nvlist_size(nvl, &buflen, NV_ENCODE_XDR) == 0); buf = kmem_alloc(buflen, KM_SLEEP); + temp = kmem_zalloc(MAXPATHLEN, KM_SLEEP); - VERIFY(nvlist_pack(config, &buf, &buflen, NV_ENCODE_XDR, + VERIFY(nvlist_pack(nvl, &buf, &buflen, NV_ENCODE_XDR, KM_SLEEP) == 0); /* @@ -263,60 +178,92 @@ spa_config_entry_write(spa_config_entry_t *entry) * 'write to temporary file, sync, move over original' to make sure we * always have a consistent view of the data. */ - (void) snprintf(pathname, sizeof (pathname), "%s/.%s", entry->sc_dir, - entry->sc_file); + (void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path); - if (vn_open(pathname, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0) != 0) - goto out; - - if (vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE, - 0, RLIM64_INFINITY, kcred, NULL) == 0 && - VOP_FSYNC(vp, FSYNC, kcred, NULL) == 0) { - (void) snprintf(pathname2, sizeof (pathname2), "%s/%s", - entry->sc_dir, entry->sc_file); - (void) vn_rename(pathname, pathname2, UIO_SYSSPACE); + if (vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0) == 0) { + if (vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE, + 0, RLIM64_INFINITY, kcred, NULL) == 0 && + VOP_FSYNC(vp, FSYNC, kcred, NULL) == 0) { + (void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE); + } + (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); + VN_RELE(vp); } - (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); - VN_RELE(vp); + (void) vn_remove(temp, UIO_SYSSPACE, RMFILE); -out: - (void) vn_remove(pathname, UIO_SYSSPACE, RMFILE); kmem_free(buf, buflen); + kmem_free(temp, MAXPATHLEN); } /* - * Synchronize all pools to disk. This must be called with the namespace lock - * held. + * Synchronize pool configuration to disk. This must be called with the + * namespace lock held. */ void -spa_config_sync(void) +spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) { - spa_t *spa = NULL; - list_t files = { 0 }; - spa_config_entry_t *entry; + spa_config_dirent_t *dp, *tdp; + nvlist_t *nvl; ASSERT(MUTEX_HELD(&spa_namespace_lock)); - list_create(&files, sizeof (spa_config_entry_t), - offsetof(spa_config_entry_t, sc_link)); + /* + * Iterate over all cachefiles for the pool, past or present. When the + * cachefile is changed, the new one is pushed onto this list, allowing + * us to update previous cachefiles that no longer contain this pool. + */ + for (dp = list_head(&target->spa_config_list); dp != NULL; + dp = list_next(&target->spa_config_list, dp)) { + spa_t *spa = NULL; + if (dp->scd_path == NULL) + continue; + + /* + * Iterate over all pools, adding any matching pools to 'nvl'. + */ + nvl = NULL; + while ((spa = spa_next(spa)) != NULL) { + if (spa == target && removing) + continue; + + mutex_enter(&spa->spa_props_lock); + tdp = list_head(&spa->spa_config_list); + if (spa->spa_config == NULL || + tdp->scd_path == NULL || + strcmp(tdp->scd_path, dp->scd_path) != 0) { + mutex_exit(&spa->spa_props_lock); + continue; + } + + if (nvl == NULL) + VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, + KM_SLEEP) == 0); + + VERIFY(nvlist_add_nvlist(nvl, spa->spa_name, + spa->spa_config) == 0); + mutex_exit(&spa->spa_props_lock); + } + + spa_config_write(dp, nvl); + nvlist_free(nvl); + } /* - * Add all known pools to the configuration list, ignoring those with - * alternate root paths. + * Remove any config entries older than the current one. */ - spa = NULL; - while ((spa = spa_next(spa)) != NULL) - spa_config_entry_add(&files, spa); - - while ((entry = list_head(&files)) != NULL) { - spa_config_entry_write(entry); - list_remove(&files, entry); - nvlist_free(entry->sc_nvl); - kmem_free(entry, sizeof (spa_config_entry_t)); + dp = list_head(&target->spa_config_list); + while ((tdp = list_next(&target->spa_config_list, dp)) != NULL) { + list_remove(&target->spa_config_list, tdp); + if (tdp->scd_path != NULL) + spa_strfree(tdp->scd_path); + kmem_free(tdp, sizeof (spa_config_dirent_t)); } spa_config_generation++; + + if (postsysevent) + spa_event_notify(target, NULL, ESC_ZFS_CONFIG_SYNC); } /* @@ -329,27 +276,25 @@ nvlist_t * spa_all_configs(uint64_t *generation) { nvlist_t *pools; - spa_t *spa; + spa_t *spa = NULL; if (*generation == spa_config_generation) return (NULL); VERIFY(nvlist_alloc(&pools, NV_UNIQUE_NAME, KM_SLEEP) == 0); - spa = NULL; mutex_enter(&spa_namespace_lock); while ((spa = spa_next(spa)) != NULL) { if (INGLOBALZONE(curproc) || zone_dataset_visible(spa_name(spa), NULL)) { - mutex_enter(&spa->spa_config_cache_lock); + mutex_enter(&spa->spa_props_lock); VERIFY(nvlist_add_nvlist(pools, spa_name(spa), spa->spa_config) == 0); - mutex_exit(&spa->spa_config_cache_lock); + mutex_exit(&spa->spa_props_lock); } } - mutex_exit(&spa_namespace_lock); - *generation = spa_config_generation; + mutex_exit(&spa_namespace_lock); return (pools); } @@ -357,11 +302,11 @@ spa_all_configs(uint64_t *generation) void spa_config_set(spa_t *spa, nvlist_t *config) { - mutex_enter(&spa->spa_config_cache_lock); + mutex_enter(&spa->spa_props_lock); if (spa->spa_config != NULL) nvlist_free(spa->spa_config); spa->spa_config = config; - mutex_exit(&spa->spa_config_cache_lock); + mutex_exit(&spa->spa_props_lock); } /* @@ -375,12 +320,16 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) nvlist_t *config, *nvroot; vdev_t *rvd = spa->spa_root_vdev; unsigned long hostid = 0; + boolean_t locked = B_FALSE; - ASSERT(spa_config_held(spa, RW_READER) || - spa_config_held(spa, RW_WRITER)); - - if (vd == NULL) + if (vd == NULL) { vd = rvd; + locked = B_TRUE; + spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER); + } + + ASSERT(spa_config_held(spa, SCL_CONFIG | SCL_STATE, RW_READER) == + (SCL_CONFIG | SCL_STATE)); /* * If txg is -1, report the current value of spa->spa_config_txg. @@ -426,6 +375,9 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0); nvlist_free(nvroot); + if (locked) + spa_config_exit(spa, SCL_CONFIG | SCL_STATE, FTAG); + return (config); } @@ -454,7 +406,7 @@ spa_config_update_common(spa_t *spa, int what, boolean_t isroot) ASSERT(MUTEX_HELD(&spa_namespace_lock)); - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); txg = spa_last_synced_txg(spa) + 1; if (what == SPA_CONFIG_UPDATE_POOL) { vdev_config_dirty(rvd); @@ -474,7 +426,7 @@ spa_config_update_common(spa_t *spa, int what, boolean_t isroot) } } } - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); /* * Wait for the mosconfig to be regenerated and synced. @@ -485,7 +437,7 @@ spa_config_update_common(spa_t *spa, int what, boolean_t isroot) * Update the global config cache to reflect the new mosconfig. */ if (!isroot) - spa_config_sync(); + spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL); if (what == SPA_CONFIG_UPDATE_POOL) spa_config_update_common(spa, SPA_CONFIG_UPDATE_VDEVS, isroot); diff --git a/zfs/lib/libzpool/spa_errlog.c b/zfs/lib/libzpool/spa_errlog.c index 162845471..c642bd768 100644 --- a/zfs/lib/libzpool/spa_errlog.c +++ b/zfs/lib/libzpool/spa_errlog.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)spa_errlog.c 1.2 06/10/02 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * Routines to manage the on-disk persistent error log. @@ -298,10 +298,7 @@ void spa_errlog_rotate(spa_t *spa) { mutex_enter(&spa->spa_errlist_lock); - - ASSERT(!spa->spa_scrub_finished); spa->spa_scrub_finished = B_TRUE; - mutex_exit(&spa->spa_errlist_lock); } diff --git a/zfs/lib/libzpool/spa_history.c b/zfs/lib/libzpool/spa_history.c index 0fa6411a1..c997240c1 100644 --- a/zfs/lib/libzpool/spa_history.c +++ b/zfs/lib/libzpool/spa_history.c @@ -20,11 +20,11 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)spa_history.c 1.5 07/07/09 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -399,6 +399,13 @@ spa_history_internal_log(history_internal_events_t event, spa_t *spa, char *str; va_list adx; + /* + * If this is part of creating a pool, not everything is + * initialized yet, so don't bother logging the internal events. + */ + if (tx->tx_txg == TXG_INITIAL) + return; + hap = kmem_alloc(sizeof (history_arg_t), KM_SLEEP); str = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP); diff --git a/zfs/lib/libzpool/spa_misc.c b/zfs/lib/libzpool/spa_misc.c index 4ec538038..36046e6df 100644 --- a/zfs/lib/libzpool/spa_misc.c +++ b/zfs/lib/libzpool/spa_misc.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)spa_misc.c 1.31 08/04/01 SMI" - #include #include #include @@ -45,6 +43,8 @@ #include #include #include +#include +#include #include "zfs_prop.h" /* @@ -74,10 +74,10 @@ * This reference count keep track of any active users of the spa_t. The * spa_t cannot be destroyed or freed while this is non-zero. Internally, * the refcount is never really 'zero' - opening a pool implicitly keeps - * some references in the DMU. Internally we check against SPA_MINREF, but + * some references in the DMU. Internally we check against spa_minref, but * present the image of a zero/non-zero value to consumers. * - * spa_config_lock (per-spa read-priority rwlock) + * spa_config_lock[] (per-spa array of rwlocks) * * This protects the spa_t from config changes, and must be held in * the following circumstances: @@ -85,13 +85,6 @@ * - RW_READER to perform I/O to the spa * - RW_WRITER to change the vdev config * - * spa_config_cache_lock (per-spa mutex) - * - * This mutex prevents the spa_config nvlist from being updated. No - * other locks are required to obtain this lock, although implicitly you - * must have the namespace lock or non-zero refcount to have any kind - * of spa_t pointer at all. - * * The locking order is fairly straightforward: * * spa_namespace_lock -> spa_refcount @@ -99,21 +92,20 @@ * The namespace lock must be acquired to increase the refcount from 0 * or to check if it is zero. * - * spa_refcount -> spa_config_lock + * spa_refcount -> spa_config_lock[] * * There must be at least one valid reference on the spa_t to acquire * the config lock. * - * spa_namespace_lock -> spa_config_lock + * spa_namespace_lock -> spa_config_lock[] * * The namespace lock must always be taken before the config lock. * * - * The spa_namespace_lock and spa_config_cache_lock can be acquired directly and - * are globally visible. + * The spa_namespace_lock can be acquired directly and is globally visible. * - * The namespace is manipulated using the following functions, all which require - * the spa_namespace_lock to be held. + * The namespace is manipulated using the following functions, all of which + * require the spa_namespace_lock to be held. * * spa_lookup() Lookup a spa_t by name. * @@ -144,9 +136,70 @@ * zero. Must be called with spa_namespace_lock * held. * - * The spa_config_lock is a form of rwlock. It must be held as RW_READER - * to perform I/O to the pool, and as RW_WRITER to change the vdev config. - * The spa_config_lock is manipulated with spa_config_{enter,exit,held}(). + * The spa_config_lock[] is an array of rwlocks, ordered as follows: + * SCL_CONFIG > SCL_STATE > SCL_ALLOC > SCL_ZIO > SCL_FREE > SCL_VDEV. + * spa_config_lock[] is manipulated with spa_config_{enter,exit,held}(). + * + * To read the configuration, it suffices to hold one of these locks as reader. + * To modify the configuration, you must hold all locks as writer. To modify + * vdev state without altering the vdev tree's topology (e.g. online/offline), + * you must hold SCL_STATE and SCL_ZIO as writer. + * + * We use these distinct config locks to avoid recursive lock entry. + * For example, spa_sync() (which holds SCL_CONFIG as reader) induces + * block allocations (SCL_ALLOC), which may require reading space maps + * from disk (dmu_read() -> zio_read() -> SCL_ZIO). + * + * The spa config locks cannot be normal rwlocks because we need the + * ability to hand off ownership. For example, SCL_ZIO is acquired + * by the issuing thread and later released by an interrupt thread. + * They do, however, obey the usual write-wanted semantics to prevent + * writer (i.e. system administrator) starvation. + * + * The lock acquisition rules are as follows: + * + * SCL_CONFIG + * Protects changes to the vdev tree topology, such as vdev + * add/remove/attach/detach. Protects the dirty config list + * (spa_config_dirty_list) and the set of spares and l2arc devices. + * + * SCL_STATE + * Protects changes to pool state and vdev state, such as vdev + * online/offline/fault/degrade/clear. Protects the dirty state list + * (spa_state_dirty_list) and global pool state (spa_state). + * + * SCL_ALLOC + * Protects changes to metaslab groups and classes. + * Held as reader by metaslab_alloc() and metaslab_claim(). + * + * SCL_ZIO + * Held by bp-level zios (those which have no io_vd upon entry) + * to prevent changes to the vdev tree. The bp-level zio implicitly + * protects all of its vdev child zios, which do not hold SCL_ZIO. + * + * SCL_FREE + * Protects changes to metaslab groups and classes. + * Held as reader by metaslab_free(). SCL_FREE is distinct from + * SCL_ALLOC, and lower than SCL_ZIO, so that we can safely free + * blocks in zio_done() while another i/o that holds either + * SCL_ALLOC or SCL_ZIO is waiting for this i/o to complete. + * + * SCL_VDEV + * Held as reader to prevent changes to the vdev tree during trivial + * inquiries such as bp_get_dasize(). SCL_VDEV is distinct from the + * other locks, and lower than all of them, to ensure that it's safe + * to acquire regardless of caller context. + * + * In addition, the following rules apply: + * + * (a) spa_props_lock protects pool properties, spa_config and spa_config_list. + * The lock ordering is SCL_CONFIG > spa_props_lock. + * + * (b) I/O operations on leaf vdevs. For any zio operation that takes + * an explicit vdev_t argument -- such as zio_ioctl(), zio_read_phys(), + * or zio_write_phys() -- the caller must ensure that the config cannot + * cannot change in the interim, and that the vdev cannot be reopened. + * SCL_STATE as reader suffices for both. * * The vdev configuration is protected by spa_vdev_enter() / spa_vdev_exit(). * @@ -157,10 +210,12 @@ * to complete, sync the updated configs to the * cache, and release the namespace lock. * - * The spa_name() function also requires either the spa_namespace_lock - * or the spa_config_lock, as both are needed to do a rename. spa_rename() is - * also implemented within this file since is requires manipulation of the - * namespace. + * vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit(). + * Like spa_vdev_enter/exit, these are convenience wrappers -- the actual + * locking is, always, based on spa_namespace_lock and spa_config_lock[]. + * + * spa_rename() is also implemented within this file since is requires + * manipulation of the namespace. */ static avl_tree_t spa_namespace_avl; @@ -191,7 +246,6 @@ int zfs_flags = 0; */ int zfs_recover = 0; -#define SPA_MINREF 5 /* spa_refcnt for an open-but-idle pool */ /* * ========================================================================== @@ -199,72 +253,120 @@ int zfs_recover = 0; * ========================================================================== */ static void -spa_config_lock_init(spa_config_lock_t *scl) +spa_config_lock_init(spa_t *spa) { - mutex_init(&scl->scl_lock, NULL, MUTEX_DEFAULT, NULL); - scl->scl_writer = NULL; - cv_init(&scl->scl_cv, NULL, CV_DEFAULT, NULL); - refcount_create(&scl->scl_count); + for (int i = 0; i < SCL_LOCKS; i++) { + spa_config_lock_t *scl = &spa->spa_config_lock[i]; + mutex_init(&scl->scl_lock, NULL, MUTEX_DEFAULT, NULL); + cv_init(&scl->scl_cv, NULL, CV_DEFAULT, NULL); + refcount_create(&scl->scl_count); + scl->scl_writer = NULL; + scl->scl_write_wanted = 0; + } } static void -spa_config_lock_destroy(spa_config_lock_t *scl) +spa_config_lock_destroy(spa_t *spa) { - mutex_destroy(&scl->scl_lock); - ASSERT(scl->scl_writer == NULL); - cv_destroy(&scl->scl_cv); - refcount_destroy(&scl->scl_count); + for (int i = 0; i < SCL_LOCKS; i++) { + spa_config_lock_t *scl = &spa->spa_config_lock[i]; + mutex_destroy(&scl->scl_lock); + cv_destroy(&scl->scl_cv); + refcount_destroy(&scl->scl_count); + ASSERT(scl->scl_writer == NULL); + ASSERT(scl->scl_write_wanted == 0); + } +} + +int +spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw) +{ + for (int i = 0; i < SCL_LOCKS; i++) { + spa_config_lock_t *scl = &spa->spa_config_lock[i]; + if (!(locks & (1 << i))) + continue; + mutex_enter(&scl->scl_lock); + if (rw == RW_READER) { + if (scl->scl_writer || scl->scl_write_wanted) { + mutex_exit(&scl->scl_lock); + spa_config_exit(spa, locks ^ (1 << i), tag); + return (0); + } + } else { + ASSERT(scl->scl_writer != curthread); + if (!refcount_is_zero(&scl->scl_count)) { + mutex_exit(&scl->scl_lock); + spa_config_exit(spa, locks ^ (1 << i), tag); + return (0); + } + scl->scl_writer = curthread; + } + (void) refcount_add(&scl->scl_count, tag); + mutex_exit(&scl->scl_lock); + } + return (1); } void -spa_config_enter(spa_t *spa, krw_t rw, void *tag) +spa_config_enter(spa_t *spa, int locks, void *tag, krw_t rw) { - spa_config_lock_t *scl = &spa->spa_config_lock; - - mutex_enter(&scl->scl_lock); - - if (rw == RW_READER) { - while (scl->scl_writer != NULL && scl->scl_writer != curthread) - cv_wait(&scl->scl_cv, &scl->scl_lock); - } else { - while (!refcount_is_zero(&scl->scl_count) && - scl->scl_writer != curthread) - cv_wait(&scl->scl_cv, &scl->scl_lock); - scl->scl_writer = curthread; + for (int i = 0; i < SCL_LOCKS; i++) { + spa_config_lock_t *scl = &spa->spa_config_lock[i]; + if (!(locks & (1 << i))) + continue; + mutex_enter(&scl->scl_lock); + if (rw == RW_READER) { + while (scl->scl_writer || scl->scl_write_wanted) { + cv_wait(&scl->scl_cv, &scl->scl_lock); + } + } else { + ASSERT(scl->scl_writer != curthread); + while (!refcount_is_zero(&scl->scl_count)) { + scl->scl_write_wanted++; + cv_wait(&scl->scl_cv, &scl->scl_lock); + scl->scl_write_wanted--; + } + scl->scl_writer = curthread; + } + (void) refcount_add(&scl->scl_count, tag); + mutex_exit(&scl->scl_lock); } - - (void) refcount_add(&scl->scl_count, tag); - - mutex_exit(&scl->scl_lock); } void -spa_config_exit(spa_t *spa, void *tag) +spa_config_exit(spa_t *spa, int locks, void *tag) { - spa_config_lock_t *scl = &spa->spa_config_lock; - - mutex_enter(&scl->scl_lock); - - ASSERT(!refcount_is_zero(&scl->scl_count)); - - if (refcount_remove(&scl->scl_count, tag) == 0) { - cv_broadcast(&scl->scl_cv); - ASSERT(scl->scl_writer == NULL || scl->scl_writer == curthread); - scl->scl_writer = NULL; /* OK in either case */ + for (int i = SCL_LOCKS - 1; i >= 0; i--) { + spa_config_lock_t *scl = &spa->spa_config_lock[i]; + if (!(locks & (1 << i))) + continue; + mutex_enter(&scl->scl_lock); + ASSERT(!refcount_is_zero(&scl->scl_count)); + if (refcount_remove(&scl->scl_count, tag) == 0) { + ASSERT(scl->scl_writer == NULL || + scl->scl_writer == curthread); + scl->scl_writer = NULL; /* OK in either case */ + cv_broadcast(&scl->scl_cv); + } + mutex_exit(&scl->scl_lock); } - - mutex_exit(&scl->scl_lock); } -boolean_t -spa_config_held(spa_t *spa, krw_t rw) +int +spa_config_held(spa_t *spa, int locks, krw_t rw) { - spa_config_lock_t *scl = &spa->spa_config_lock; + int locks_held = 0; - if (rw == RW_READER) - return (!refcount_is_zero(&scl->scl_count)); - else - return (scl->scl_writer == curthread); + for (int i = 0; i < SCL_LOCKS; i++) { + spa_config_lock_t *scl = &spa->spa_config_lock[i]; + if (!(locks & (1 << i))) + continue; + if ((rw == RW_READER && !refcount_is_zero(&scl->scl_count)) || + (rw == RW_WRITER && scl->scl_writer == curthread)) + locks_held |= 1 << i; + } + + return (locks_held); } /* @@ -280,7 +382,8 @@ spa_config_held(spa_t *spa, krw_t rw) spa_t * spa_lookup(const char *name) { - spa_t search, *spa; + static spa_t search; /* spa_t is large; don't allocate on stack */ + spa_t *spa; avl_index_t where; char c; char *cp; @@ -297,7 +400,7 @@ spa_lookup(const char *name) *cp = '\0'; } - search.spa_name = (char *)name; + (void) strlcpy(search.spa_name, name, sizeof (search.spa_name)); spa = avl_find(&spa_namespace_avl, &search, &where); if (cp) @@ -315,16 +418,14 @@ spa_t * spa_add(const char *name, const char *altroot) { spa_t *spa; + spa_config_dirent_t *dp; ASSERT(MUTEX_HELD(&spa_namespace_lock)); spa = kmem_zalloc(sizeof (spa_t), KM_SLEEP); - rw_init(&spa->spa_traverse_lock, NULL, RW_DEFAULT, NULL); - - mutex_init(&spa->spa_uberblock_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&spa->spa_async_lock, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&spa->spa_config_cache_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&spa->spa_async_root_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL); @@ -333,20 +434,21 @@ spa_add(const char *name, const char *altroot) mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL); cv_init(&spa->spa_async_cv, NULL, CV_DEFAULT, NULL); - cv_init(&spa->spa_scrub_cv, NULL, CV_DEFAULT, NULL); + cv_init(&spa->spa_async_root_cv, NULL, CV_DEFAULT, NULL); cv_init(&spa->spa_scrub_io_cv, NULL, CV_DEFAULT, NULL); + cv_init(&spa->spa_suspend_cv, NULL, CV_DEFAULT, NULL); - spa->spa_name = spa_strdup(name); + (void) strlcpy(spa->spa_name, name, sizeof (spa->spa_name)); spa->spa_state = POOL_STATE_UNINITIALIZED; spa->spa_freeze_txg = UINT64_MAX; spa->spa_final_txg = UINT64_MAX; refcount_create(&spa->spa_refcount); - spa_config_lock_init(&spa->spa_config_lock); + spa_config_lock_init(spa); avl_add(&spa_namespace_avl, spa); - mutex_init(&spa->spa_zio_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&spa->spa_suspend_lock, NULL, MUTEX_DEFAULT, NULL); /* * Set the alternate root, if there is one. @@ -356,6 +458,16 @@ spa_add(const char *name, const char *altroot) spa_active_count++; } + /* + * Every pool starts with the default cachefile + */ + list_create(&spa->spa_config_list, sizeof (spa_config_dirent_t), + offsetof(spa_config_dirent_t, scd_link)); + + dp = kmem_zalloc(sizeof (spa_config_dirent_t), KM_SLEEP); + dp->scd_path = spa_strdup(spa_config_path); + list_insert_head(&spa->spa_config_list, dp); + return (spa); } @@ -367,9 +479,10 @@ spa_add(const char *name, const char *altroot) void spa_remove(spa_t *spa) { + spa_config_dirent_t *dp; + ASSERT(MUTEX_HELD(&spa_namespace_lock)); ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); - ASSERT(spa->spa_scrub_thread == NULL); avl_remove(&spa_namespace_avl, spa); cv_broadcast(&spa_namespace_cv); @@ -379,36 +492,35 @@ spa_remove(spa_t *spa) spa_active_count--; } - if (spa->spa_name) - spa_strfree(spa->spa_name); + while ((dp = list_head(&spa->spa_config_list)) != NULL) { + list_remove(&spa->spa_config_list, dp); + if (dp->scd_path != NULL) + spa_strfree(dp->scd_path); + kmem_free(dp, sizeof (spa_config_dirent_t)); + } - if (spa->spa_config_dir) - spa_strfree(spa->spa_config_dir); - if (spa->spa_config_file) - spa_strfree(spa->spa_config_file); + list_destroy(&spa->spa_config_list); spa_config_set(spa, NULL); refcount_destroy(&spa->spa_refcount); - spa_config_lock_destroy(&spa->spa_config_lock); - - rw_destroy(&spa->spa_traverse_lock); + spa_config_lock_destroy(spa); cv_destroy(&spa->spa_async_cv); - cv_destroy(&spa->spa_scrub_cv); + cv_destroy(&spa->spa_async_root_cv); cv_destroy(&spa->spa_scrub_io_cv); + cv_destroy(&spa->spa_suspend_cv); - mutex_destroy(&spa->spa_uberblock_lock); mutex_destroy(&spa->spa_async_lock); - mutex_destroy(&spa->spa_config_cache_lock); + mutex_destroy(&spa->spa_async_root_lock); mutex_destroy(&spa->spa_scrub_lock); mutex_destroy(&spa->spa_errlog_lock); mutex_destroy(&spa->spa_errlist_lock); mutex_destroy(&spa->spa_sync_bplist.bpl_lock); mutex_destroy(&spa->spa_history_lock); mutex_destroy(&spa->spa_props_lock); - mutex_destroy(&spa->spa_zio_lock); + mutex_destroy(&spa->spa_suspend_lock); kmem_free(spa, sizeof (spa_t)); } @@ -441,9 +553,8 @@ spa_next(spa_t *prev) void spa_open_ref(spa_t *spa, void *tag) { - ASSERT(refcount_count(&spa->spa_refcount) > SPA_MINREF || + ASSERT(refcount_count(&spa->spa_refcount) >= spa->spa_minref || MUTEX_HELD(&spa_namespace_lock)); - (void) refcount_add(&spa->spa_refcount, tag); } @@ -454,15 +565,14 @@ spa_open_ref(spa_t *spa, void *tag) void spa_close(spa_t *spa, void *tag) { - ASSERT(refcount_count(&spa->spa_refcount) > SPA_MINREF || + ASSERT(refcount_count(&spa->spa_refcount) > spa->spa_minref || MUTEX_HELD(&spa_namespace_lock)); - (void) refcount_remove(&spa->spa_refcount, tag); } /* * Check to see if the spa refcount is zero. Must be called with - * spa_namespace_lock held. We really compare against SPA_MINREF, which is the + * spa_namespace_lock held. We really compare against spa_minref, which is the * number of references acquired when opening a pool */ boolean_t @@ -470,7 +580,7 @@ spa_refcount_zero(spa_t *spa) { ASSERT(MUTEX_HELD(&spa_namespace_lock)); - return (refcount_count(&spa->spa_refcount) == SPA_MINREF); + return (refcount_count(&spa->spa_refcount) == spa->spa_minref); } /* @@ -544,13 +654,12 @@ spa_aux_remove(vdev_t *vd, avl_tree_t *avl) } boolean_t -spa_aux_exists(uint64_t guid, uint64_t *pool, avl_tree_t *avl) +spa_aux_exists(uint64_t guid, uint64_t *pool, int *refcnt, avl_tree_t *avl) { spa_aux_t search, *found; - avl_index_t where; search.aux_guid = guid; - found = avl_find(avl, &search, &where); + found = avl_find(avl, &search, NULL); if (pool) { if (found) @@ -559,6 +668,13 @@ spa_aux_exists(uint64_t guid, uint64_t *pool, avl_tree_t *avl) *pool = 0ULL; } + if (refcnt) { + if (found) + *refcnt = found->aux_count; + else + *refcnt = 0; + } + return (found != NULL); } @@ -625,12 +741,12 @@ spa_spare_remove(vdev_t *vd) } boolean_t -spa_spare_exists(uint64_t guid, uint64_t *pool) +spa_spare_exists(uint64_t guid, uint64_t *pool, int *refcnt) { boolean_t found; mutex_enter(&spa_spare_lock); - found = spa_aux_exists(guid, pool, &spa_spare_avl); + found = spa_aux_exists(guid, pool, refcnt, &spa_spare_avl); mutex_exit(&spa_spare_lock); return (found); @@ -683,7 +799,7 @@ spa_l2cache_exists(uint64_t guid, uint64_t *pool) boolean_t found; mutex_enter(&spa_l2cache_lock); - found = spa_aux_exists(guid, pool, &spa_l2cache_avl); + found = spa_aux_exists(guid, pool, NULL, &spa_l2cache_avl); mutex_exit(&spa_l2cache_lock); return (found); @@ -720,14 +836,7 @@ spa_vdev_enter(spa_t *spa) { mutex_enter(&spa_namespace_lock); - /* - * Suspend scrub activity while we mess with the config. We must do - * this after acquiring the namespace lock to avoid a 3-way deadlock - * with spa_scrub_stop() and the scrub thread. - */ - spa_scrub_suspend(spa); - - spa_config_enter(spa, RW_WRITER, spa); + spa_config_enter(spa, SCL_ALL, spa, RW_WRITER); return (spa_last_synced_txg(spa) + 1); } @@ -745,6 +854,8 @@ spa_vdev_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error) ASSERT(txg > spa_last_synced_txg(spa)); + spa->spa_pending_vdev = NULL; + /* * Reassess the DTLs. */ @@ -753,17 +864,12 @@ spa_vdev_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error) /* * If the config changed, notify the scrub thread that it must restart. */ - if (error == 0 && !list_is_empty(&spa->spa_dirty_list)) { + if (error == 0 && !list_is_empty(&spa->spa_config_dirty_list)) { + dsl_pool_scrub_restart(spa->spa_dsl_pool); config_changed = B_TRUE; - spa_scrub_restart(spa, txg); } - spa_config_exit(spa, spa); - - /* - * Allow scrubbing to resume. - */ - spa_scrub_resume(spa); + spa_config_exit(spa, SCL_ALL, spa); /* * Note: this txg_wait_synced() is important because it ensures @@ -782,13 +888,33 @@ spa_vdev_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error) * If the config changed, update the config cache. */ if (config_changed) - spa_config_sync(); + spa_config_sync(spa, B_FALSE, B_TRUE); mutex_exit(&spa_namespace_lock); return (error); } +/* + * Lock the given spa_t for the purpose of changing vdev state. + */ +void +spa_vdev_state_enter(spa_t *spa) +{ + spa_config_enter(spa, SCL_STATE_ALL, spa, RW_WRITER); +} + +int +spa_vdev_state_exit(spa_t *spa, vdev_t *vd, int error) +{ + if (vd != NULL) + vdev_state_dirty(vd->vdev_top); + + spa_config_exit(spa, SCL_STATE_ALL, spa); + + return (error); +} + /* * ========================================================================== * Miscellaneous functions @@ -816,11 +942,10 @@ spa_rename(const char *name, const char *newname) return (err); } - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); avl_remove(&spa_namespace_avl, spa); - spa_strfree(spa->spa_name); - spa->spa_name = spa_strdup(newname); + (void) strlcpy(spa->spa_name, newname, sizeof (spa->spa_name)); avl_add(&spa_namespace_avl, spa); /* @@ -830,14 +955,14 @@ spa_rename(const char *name, const char *newname) */ vdev_config_dirty(spa->spa_root_vdev); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); txg_wait_synced(spa->spa_dsl_pool, 0); /* * Sync the updated config cache. */ - spa_config_sync(); + spa_config_sync(spa, B_FALSE, B_TRUE); spa_close(spa, FTAG); @@ -968,12 +1093,12 @@ spa_freeze(spa_t *spa) { uint64_t freeze_txg = 0; - spa_config_enter(spa, RW_WRITER, FTAG); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); if (spa->spa_freeze_txg == UINT64_MAX) { freeze_txg = spa_last_synced_txg(spa) + TXG_SIZE; spa->spa_freeze_txg = freeze_txg; } - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_ALL, FTAG); if (freeze_txg != 0) txg_wait_synced(spa_get_dsl(spa), freeze_txg); } @@ -994,16 +1119,10 @@ zfs_panic_recover(const char *fmt, ...) * ========================================================================== */ -krwlock_t * -spa_traverse_rwlock(spa_t *spa) +boolean_t +spa_shutting_down(spa_t *spa) { - return (&spa->spa_traverse_lock); -} - -int -spa_traverse_wanted(spa_t *spa) -{ - return (spa->spa_traverse_wanted); + return (spa->spa_async_suspended); } dsl_pool_t * @@ -1042,13 +1161,6 @@ spa_sync_pass(spa_t *spa) char * spa_name(spa_t *spa) { - /* - * Accessing the name requires holding either the namespace lock or the - * config lock, both of which are required to do a rename. - */ - ASSERT(MUTEX_HELD(&spa_namespace_lock) || - spa_config_held(spa, RW_READER)); - return (spa->spa_name); } @@ -1079,7 +1191,7 @@ spa_first_txg(spa_t *spa) return (spa->spa_first_txg); } -int +pool_state_t spa_state(spa_t *spa) { return (spa->spa_state); @@ -1144,6 +1256,12 @@ spa_get_failmode(spa_t *spa) return (spa->spa_failmode); } +boolean_t +spa_suspended(spa_t *spa) +{ + return (spa->spa_suspended); +} + uint64_t spa_version(spa_t *spa) { @@ -1171,7 +1289,7 @@ bp_get_dasize(spa_t *spa, const blkptr_t *bp) if (!spa->spa_deflate) return (BP_GET_ASIZE(bp)); - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); for (i = 0; i < SPA_DVAS_PER_BP; i++) { vdev_t *vd = vdev_lookup_top(spa, DVA_GET_VDEV(&bp->blk_dva[i])); @@ -1179,7 +1297,7 @@ bp_get_dasize(spa_t *spa, const blkptr_t *bp) sz += (DVA_GET_ASIZE(&bp->blk_dva[i]) >> SPA_MINBLOCKSHIFT) * vd->vdev_deflate_ratio; } - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_VDEV, FTAG); return (sz); } @@ -1244,11 +1362,14 @@ spa_init(int mode) zfs_prop_init(); zpool_prop_init(); spa_config_load(); + l2arc_start(); } void spa_fini(void) { + l2arc_stop(); + spa_evict_all(); vdev_cache_stat_fini(); @@ -1278,3 +1399,12 @@ spa_has_slogs(spa_t *spa) { return (spa->spa_log_class->mc_rotor != NULL); } + +/* + * Return whether this pool is the root pool. + */ +boolean_t +spa_is_root(spa_t *spa) +{ + return (spa->spa_is_root); +} diff --git a/zfs/lib/libzpool/space_map.c b/zfs/lib/libzpool/space_map.c index b1e6bc15f..0a1fd59ea 100644 --- a/zfs/lib/libzpool/space_map.c +++ b/zfs/lib/libzpool/space_map.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)space_map.c 1.7 08/03/11 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/txg.c b/zfs/lib/libzpool/txg.c index f810a0dc6..2bbf2f086 100644 --- a/zfs/lib/libzpool/txg.c +++ b/zfs/lib/libzpool/txg.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)txg.c 1.4 08/03/20 SMI" - #include #include #include @@ -39,13 +37,6 @@ static void txg_sync_thread(dsl_pool_t *dp); static void txg_quiesce_thread(dsl_pool_t *dp); int zfs_txg_timeout = 30; /* max seconds worth of delta per txg */ -int zfs_txg_synctime = 5; /* target seconds to sync a txg */ - -int zfs_write_limit_shift = 3; /* 1/8th of physical memory */ - -uint64_t zfs_write_limit_min = 32 << 20; /* min write limit is 32MB */ -uint64_t zfs_write_limit_max = 0; /* max data payload per txg */ -uint64_t zfs_write_limit_inflated = 0; /* * Prepare the txg subsystem. @@ -121,7 +112,12 @@ txg_sync_start(dsl_pool_t *dp) tx->tx_quiesce_thread = thread_create(NULL, 0, txg_quiesce_thread, dp, 0, &p0, TS_RUN, minclsyspri); - tx->tx_sync_thread = thread_create(NULL, 0, txg_sync_thread, + /* + * The sync thread can need a larger-than-default stack size on + * 32-bit x86. This is due in part to nested pools and + * scrub_visitbp() recursion. + */ + tx->tx_sync_thread = thread_create(NULL, 12<<10, txg_sync_thread, dp, 0, &p0, TS_RUN, minclsyspri); mutex_exit(&tx->tx_sync_lock); @@ -275,23 +271,24 @@ txg_sync_thread(dsl_pool_t *dp) { tx_state_t *tx = &dp->dp_tx; callb_cpr_t cpr; - uint64_t timeout, start, delta, timer; - int target; + uint64_t start, delta; txg_thread_enter(tx, &cpr); start = delta = 0; - timeout = zfs_txg_timeout * hz; for (;;) { - uint64_t txg, written; + uint64_t timer, timeout = zfs_txg_timeout * hz; + uint64_t txg; /* - * We sync when there's someone waiting on us, or the - * quiesce thread has handed off a txg to us, or we have - * reached our timeout. + * We sync when we're scrubbing, there's someone waiting + * on us, or the quiesce thread has handed off a txg to + * us, or we have reached our timeout. */ timer = (delta >= timeout ? 0 : timeout - delta); - while (!tx->tx_exiting && timer > 0 && + while ((dp->dp_scrub_func == SCRUB_FUNC_NONE || + spa_shutting_down(dp->dp_spa)) && + !tx->tx_exiting && timer > 0 && tx->tx_synced_txg >= tx->tx_sync_txg_waiting && tx->tx_quiesced_txg == 0) { dprintf("waiting; tx_synced=%llu waiting=%llu dp=%p\n", @@ -331,51 +328,11 @@ txg_sync_thread(dsl_pool_t *dp) dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n", txg, tx->tx_quiesce_txg_waiting, tx->tx_sync_txg_waiting); mutex_exit(&tx->tx_sync_lock); + start = lbolt; spa_sync(dp->dp_spa, txg); delta = lbolt - start; - written = dp->dp_space_towrite[txg & TXG_MASK]; - dp->dp_space_towrite[txg & TXG_MASK] = 0; - ASSERT(dp->dp_tempreserved[txg & TXG_MASK] == 0); - - /* - * If the write limit max has not been explicitly set, set it - * to a fraction of available phisical memory (default 1/8th). - * Note that we must inflate the limit because the spa - * inflates write sizes to account for data replication. - * Check this each sync phase to catch changing memory size. - */ - if (zfs_write_limit_inflated == 0 || - (zfs_write_limit_shift && zfs_write_limit_max != - physmem * PAGESIZE >> zfs_write_limit_shift)) { - zfs_write_limit_max = - physmem * PAGESIZE >> zfs_write_limit_shift; - zfs_write_limit_inflated = - spa_get_asize(dp->dp_spa, zfs_write_limit_max); - if (zfs_write_limit_min > zfs_write_limit_inflated) - zfs_write_limit_inflated = zfs_write_limit_min; - } - - /* - * Attempt to keep the sync time consistant by adjusting the - * amount of write traffic allowed into each transaction group. - */ - target = zfs_txg_synctime * hz; - if (delta > target) { - uint64_t old = MIN(dp->dp_write_limit, written); - - dp->dp_write_limit = MAX(zfs_write_limit_min, - old * target / delta); - } else if (written >= dp->dp_write_limit && - delta >> 3 < target >> 3) { - uint64_t rescale = - MIN((100 * target) / delta, 200); - - dp->dp_write_limit = MIN(zfs_write_limit_inflated, - written * rescale / 100); - } - mutex_enter(&tx->tx_sync_lock); rw_enter(&tx->tx_suspend, RW_WRITER); tx->tx_synced_txg = txg; @@ -502,13 +459,22 @@ txg_wait_open(dsl_pool_t *dp, uint64_t txg) mutex_exit(&tx->tx_sync_lock); } -int +boolean_t txg_stalled(dsl_pool_t *dp) { tx_state_t *tx = &dp->dp_tx; return (tx->tx_quiesce_txg_waiting > tx->tx_open_txg); } +boolean_t +txg_sync_waiting(dsl_pool_t *dp) +{ + tx_state_t *tx = &dp->dp_tx; + + return (tx->tx_syncing_txg <= tx->tx_sync_txg_waiting || + tx->tx_quiesced_txg != 0); +} + void txg_suspend(dsl_pool_t *dp) { diff --git a/zfs/lib/libzpool/uberblock.c b/zfs/lib/libzpool/uberblock.c index 3afb08a5b..34d7e0c3a 100644 --- a/zfs/lib/libzpool/uberblock.c +++ b/zfs/lib/libzpool/uberblock.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)uberblock.c 1.3 06/04/06 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/unique.c b/zfs/lib/libzpool/unique.c index ea7ec8854..fbe7b619a 100644 --- a/zfs/lib/libzpool/unique.c +++ b/zfs/lib/libzpool/unique.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)unique.c 1.3 07/08/02 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/vdev.c b/zfs/lib/libzpool/vdev.c index ec92c2201..16a27e514 100644 --- a/zfs/lib/libzpool/vdev.c +++ b/zfs/lib/libzpool/vdev.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)vdev.c 1.33 07/11/27 SMI" - #include #include #include @@ -40,6 +38,7 @@ #include #include #include +#include /* * Virtual device management. @@ -57,8 +56,8 @@ static vdev_ops_t *vdev_ops_table[] = { NULL }; -/* maximum scrub/resilver I/O queue */ -int zfs_scrub_limit = 70; +/* maximum scrub/resilver I/O queue per leaf vdev */ +int zfs_scrub_limit = 10; /* * Given a vdev type, return the appropriate ops vector. @@ -136,11 +135,12 @@ vdev_lookup_top(spa_t *spa, uint64_t vdev) { vdev_t *rvd = spa->spa_root_vdev; - ASSERT(spa_config_held(spa, RW_READER) || - curthread == spa->spa_scrub_thread); + ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0); - if (vdev < rvd->vdev_children) + if (vdev < rvd->vdev_children) { + ASSERT(rvd->vdev_child[vdev] != NULL); return (rvd->vdev_child[vdev]); + } return (NULL); } @@ -169,7 +169,7 @@ vdev_add_child(vdev_t *pvd, vdev_t *cvd) uint64_t id = cvd->vdev_id; vdev_t **newchild; - ASSERT(spa_config_held(cvd->vdev_spa, RW_WRITER)); + ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL); ASSERT(cvd->vdev_parent == NULL); cvd->vdev_parent = pvd; @@ -252,7 +252,7 @@ vdev_compact_children(vdev_t *pvd) int oldc = pvd->vdev_children; int newc, c; - ASSERT(spa_config_held(pvd->vdev_spa, RW_WRITER)); + ASSERT(spa_config_held(pvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL); for (c = newc = 0; c < oldc; c++) if (pvd->vdev_child[c]) @@ -315,6 +315,7 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops) mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&vd->vdev_stat_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&vd->vdev_probe_lock, NULL, MUTEX_DEFAULT, NULL); space_map_create(&vd->vdev_dtl_map, 0, -1ULL, 0, &vd->vdev_dtl_lock); space_map_create(&vd->vdev_dtl_scrub, 0, -1ULL, 0, &vd->vdev_dtl_lock); txg_list_create(&vd->vdev_ms_list, @@ -342,7 +343,7 @@ vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id, uint64_t guid = 0, islog, nparity; vdev_t *vd; - ASSERT(spa_config_held(spa, RW_WRITER)); + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0) return (EINVAL); @@ -445,8 +446,9 @@ vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id, * Look for the 'not present' flag. This will only be set if the device * was not present at the time of import. */ - (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, - &vd->vdev_not_present); + if (!spa->spa_import_faulted) + (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, + &vd->vdev_not_present); /* * Get the alignment requirement. @@ -468,13 +470,17 @@ vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id, /* * If we're a leaf vdev, try to load the DTL object and other state. */ - if (vd->vdev_ops->vdev_op_leaf && alloctype == VDEV_ALLOC_LOAD) { - (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DTL, - &vd->vdev_dtl.smo_object); + if (vd->vdev_ops->vdev_op_leaf && + (alloctype == VDEV_ALLOC_LOAD || alloctype == VDEV_ALLOC_L2CACHE)) { + if (alloctype == VDEV_ALLOC_LOAD) { + (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DTL, + &vd->vdev_dtl.smo_object); + (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_UNSPARE, + &vd->vdev_unspare); + } (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &vd->vdev_offline); - (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_UNSPARE, - &vd->vdev_unspare); + /* * When importing a pool, we want to ignore the persistent fault * state, as the diagnosis made on another system may not be @@ -512,8 +518,7 @@ vdev_free(vdev_t *vd) */ vdev_close(vd); - - ASSERT(!list_link_active(&vd->vdev_dirty_node)); + ASSERT(!list_link_active(&vd->vdev_config_dirty_node)); /* * Free all children. @@ -569,6 +574,7 @@ vdev_free(vdev_t *vd) mutex_exit(&vd->vdev_dtl_lock); mutex_destroy(&vd->vdev_dtl_lock); mutex_destroy(&vd->vdev_stat_lock); + mutex_destroy(&vd->vdev_probe_lock); if (vd == spa->spa_root_vdev) spa->spa_root_vdev = NULL; @@ -623,11 +629,16 @@ vdev_top_transfer(vdev_t *svd, vdev_t *tvd) (void) txg_list_add(&spa->spa_vdev_txg_list, tvd, t); } - if (list_link_active(&svd->vdev_dirty_node)) { + if (list_link_active(&svd->vdev_config_dirty_node)) { vdev_config_clean(svd); vdev_config_dirty(tvd); } + if (list_link_active(&svd->vdev_state_dirty_node)) { + vdev_state_clean(svd); + vdev_state_dirty(tvd); + } + tvd->vdev_deflate_ratio = svd->vdev_deflate_ratio; svd->vdev_deflate_ratio = 0; @@ -659,7 +670,7 @@ vdev_add_parent(vdev_t *cvd, vdev_ops_t *ops) vdev_t *pvd = cvd->vdev_parent; vdev_t *mvd; - ASSERT(spa_config_held(spa, RW_WRITER)); + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); mvd = vdev_alloc_common(spa, cvd->vdev_id, 0, ops); @@ -688,7 +699,7 @@ vdev_remove_parent(vdev_t *cvd) vdev_t *mvd = cvd->vdev_parent; vdev_t *pvd = mvd->vdev_parent; - ASSERT(spa_config_held(cvd->vdev_spa, RW_WRITER)); + ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL); ASSERT(mvd->vdev_children == 1); ASSERT(mvd->vdev_ops == &vdev_mirror_ops || @@ -698,22 +709,16 @@ vdev_remove_parent(vdev_t *cvd) vdev_remove_child(mvd, cvd); vdev_remove_child(pvd, mvd); + /* + * If cvd will replace mvd as a top-level vdev, preserve mvd's guid. + * Otherwise, we could have detached an offline device, and when we + * go to import the pool we'll think we have two top-level vdevs, + * instead of a different version of the same top-level vdev. + */ + if (mvd->vdev_top == mvd) + cvd->vdev_guid = cvd->vdev_guid_sum = mvd->vdev_guid; cvd->vdev_id = mvd->vdev_id; vdev_add_child(pvd, cvd); - /* - * If we created a new toplevel vdev, then we need to change the child's - * vdev GUID to match the old toplevel vdev. Otherwise, we could have - * detached an offline device, and when we go to import the pool we'll - * think we have two toplevel vdevs, instead of a different version of - * the same toplevel vdev. - */ - if (cvd->vdev_top == cvd) { - pvd->vdev_guid_sum -= cvd->vdev_guid; - cvd->vdev_guid_sum -= cvd->vdev_guid; - cvd->vdev_guid = mvd->vdev_guid; - cvd->vdev_guid_sum += mvd->vdev_guid; - pvd->vdev_guid_sum += cvd->vdev_guid; - } vdev_top_update(cvd->vdev_top, cvd->vdev_top); if (cvd == cvd->vdev_top) @@ -738,8 +743,6 @@ vdev_metaslab_init(vdev_t *vd, uint64_t txg) if (vd->vdev_ms_shift == 0) /* not being allocated from yet */ return (0); - dprintf("%s oldc %llu newc %llu\n", vdev_description(vd), oldc, newc); - ASSERT(oldc <= newc); if (vd->vdev_islog) @@ -801,19 +804,110 @@ vdev_metaslab_fini(vdev_t *vd) } } -int -vdev_probe(vdev_t *vd) +typedef struct vdev_probe_stats { + boolean_t vps_readable; + boolean_t vps_writeable; + int vps_flags; + zio_t *vps_root; + vdev_t *vps_vd; +} vdev_probe_stats_t; + +static void +vdev_probe_done(zio_t *zio) { - if (vd == NULL) - return (EINVAL); + vdev_probe_stats_t *vps = zio->io_private; + vdev_t *vd = vps->vps_vd; - /* - * Right now we only support status checks on the leaf vdevs. - */ - if (vd->vdev_ops->vdev_op_leaf) - return (vd->vdev_ops->vdev_op_probe(vd)); + if (zio->io_type == ZIO_TYPE_READ) { + ASSERT(zio->io_vd == vd); + if (zio->io_error == 0) + vps->vps_readable = 1; + if (zio->io_error == 0 && (spa_mode & FWRITE)) { + zio_nowait(zio_write_phys(vps->vps_root, vd, + zio->io_offset, zio->io_size, zio->io_data, + ZIO_CHECKSUM_OFF, vdev_probe_done, vps, + ZIO_PRIORITY_SYNC_WRITE, vps->vps_flags, B_TRUE)); + } else { + zio_buf_free(zio->io_data, zio->io_size); + } + } else if (zio->io_type == ZIO_TYPE_WRITE) { + ASSERT(zio->io_vd == vd); + if (zio->io_error == 0) + vps->vps_writeable = 1; + zio_buf_free(zio->io_data, zio->io_size); + } else if (zio->io_type == ZIO_TYPE_NULL) { + ASSERT(zio->io_vd == NULL); + ASSERT(zio == vps->vps_root); - return (0); + vd->vdev_cant_read |= !vps->vps_readable; + vd->vdev_cant_write |= !vps->vps_writeable; + + if (vdev_readable(vd) && + (vdev_writeable(vd) || !(spa_mode & FWRITE))) { + zio->io_error = 0; + } else { + ASSERT(zio->io_error != 0); + zfs_ereport_post(FM_EREPORT_ZFS_PROBE_FAILURE, + zio->io_spa, vd, NULL, 0, 0); + zio->io_error = ENXIO; + } + kmem_free(vps, sizeof (*vps)); + } +} + +/* + * Determine whether this device is accessible by reading and writing + * to several known locations: the pad regions of each vdev label + * but the first (which we leave alone in case it contains a VTOC). + */ +zio_t * +vdev_probe(vdev_t *vd, zio_t *pio) +{ + spa_t *spa = vd->vdev_spa; + vdev_probe_stats_t *vps; + zio_t *zio; + + vps = kmem_zalloc(sizeof (*vps), KM_SLEEP); + + vps->vps_flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_PROBE | + ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_AGGREGATE | ZIO_FLAG_DONT_RETRY; + + if (spa_config_held(spa, SCL_ZIO, RW_WRITER)) { + /* + * vdev_cant_read and vdev_cant_write can only transition + * from TRUE to FALSE when we have the SCL_ZIO lock as writer; + * otherwise they can only transition from FALSE to TRUE. + * This ensures that any zio looking at these values can + * assume that failures persist for the life of the I/O. + * That's important because when a device has intermittent + * connectivity problems, we want to ensure that they're + * ascribed to the device (ENXIO) and not the zio (EIO). + * + * Since we hold SCL_ZIO as writer here, clear both values + * so the probe can reevaluate from first principles. + */ + vps->vps_flags |= ZIO_FLAG_CONFIG_WRITER; + vd->vdev_cant_read = B_FALSE; + vd->vdev_cant_write = B_FALSE; + } + + ASSERT(vd->vdev_ops->vdev_op_leaf); + + zio = zio_null(pio, spa, vdev_probe_done, vps, vps->vps_flags); + + vps->vps_root = zio; + vps->vps_vd = vd; + + for (int l = 1; l < VDEV_LABELS; l++) { + zio_nowait(zio_read_phys(zio, vd, + vdev_label_offset(vd->vdev_psize, l, + offsetof(vdev_label_t, vl_pad)), + VDEV_SKIP_SIZE, zio_buf_alloc(VDEV_SKIP_SIZE), + ZIO_CHECKSUM_OFF, vdev_probe_done, vps, + ZIO_PRIORITY_SYNC_READ, vps->vps_flags, B_TRUE)); + } + + return (zio); } /* @@ -832,11 +926,6 @@ vdev_open(vdev_t *vd) vd->vdev_state == VDEV_STATE_CANT_OPEN || vd->vdev_state == VDEV_STATE_OFFLINE); - if (vd->vdev_fault_mode == VDEV_FAULT_COUNT) - vd->vdev_fault_arg >>= 1; - else - vd->vdev_fault_mode = VDEV_FAULT_NONE; - vd->vdev_stat.vs_aux = VDEV_AUX_NONE; if (!vd->vdev_removed && vd->vdev_faulted) { @@ -945,10 +1034,10 @@ vdev_open(vdev_t *vd) * Ensure we can issue some IO before declaring the * vdev open for business. */ - error = vdev_probe(vd); - if (error) { + if (vd->vdev_ops->vdev_op_leaf && + (error = zio_wait(vdev_probe(vd, NULL))) != 0) { vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN, - VDEV_AUX_OPEN_FAILED); + VDEV_AUX_IO_FAILURE); return (error); } @@ -965,16 +1054,17 @@ vdev_open(vdev_t *vd) } /* - * This allows the ZFS DE to close cases appropriately. If a device - * goes away and later returns, we want to close the associated case. - * But it's not enough to simply post this only when a device goes from - * CANT_OPEN -> HEALTHY. If we reboot the system and the device is - * back, we also need to close the case (otherwise we will try to replay - * it). So we have to post this notifier every time. Since this only - * occurs during pool open or error recovery, this should not be an - * issue. + * If a leaf vdev has a DTL, and seems healthy, then kick off a + * resilver. But don't do this if we are doing a reopen for a + * scrub, since this would just restart the scrub we are already + * doing. */ - zfs_post_ok(vd->vdev_spa, vd); + if (vd->vdev_children == 0 && !vd->vdev_spa->spa_scrub_reopen) { + mutex_enter(&vd->vdev_dtl_lock); + if (vd->vdev_dtl_map.sm_space != 0 && vdev_writeable(vd)) + spa_async_request(vd->vdev_spa, SPA_ASYNC_RESILVER); + mutex_exit(&vd->vdev_dtl_lock); + } return (0); } @@ -995,7 +1085,7 @@ vdev_validate(vdev_t *vd) spa_t *spa = vd->vdev_spa; int c; nvlist_t *label; - uint64_t guid; + uint64_t guid, top_guid; uint64_t state; for (c = 0; c < vd->vdev_children; c++) @@ -1007,7 +1097,7 @@ vdev_validate(vdev_t *vd) * any further validation. Otherwise, label I/O will fail and we will * overwrite the previous state. */ - if (vd->vdev_ops->vdev_op_leaf && !vdev_is_dead(vd)) { + if (vd->vdev_ops->vdev_op_leaf && vdev_readable(vd)) { if ((label = vdev_label_read_config(vd)) == NULL) { vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN, @@ -1023,8 +1113,20 @@ vdev_validate(vdev_t *vd) return (0); } + /* + * If this vdev just became a top-level vdev because its + * sibling was detached, it will have adopted the parent's + * vdev guid -- but the label may or may not be on disk yet. + * Fortunately, either version of the label will have the + * same top guid, so if we're a top-level vdev, we can + * safely compare to that instead. + */ if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, - &guid) != 0 || guid != vd->vdev_guid) { + &guid) != 0 || + nvlist_lookup_uint64(label, ZPOOL_CONFIG_TOP_GUID, + &top_guid) != 0 || + (vd->vdev_guid != guid && + (vd->vdev_guid != top_guid || vd != vd->vdev_top))) { vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN, VDEV_AUX_CORRUPT_DATA); nvlist_free(label); @@ -1044,14 +1146,15 @@ vdev_validate(vdev_t *vd) if (spa->spa_load_state == SPA_LOAD_OPEN && state != POOL_STATE_ACTIVE) return (EBADF); - } - /* - * If we were able to open and validate a vdev that was previously - * marked permanently unavailable, clear that state now. - */ - if (vd->vdev_not_present) - vd->vdev_not_present = 0; + /* + * If we were able to open and validate a vdev that was + * previously marked permanently unavailable, clear that state + * now. + */ + if (vd->vdev_not_present) + vd->vdev_not_present = 0; + } return (0); } @@ -1085,7 +1188,7 @@ vdev_reopen(vdev_t *vd) { spa_t *spa = vd->vdev_spa; - ASSERT(spa_config_held(spa, RW_WRITER)); + ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL); vdev_close(vd); (void) vdev_open(vd); @@ -1095,7 +1198,18 @@ vdev_reopen(vdev_t *vd) * Otherwise, a device with an invalid label could be successfully * opened in response to vdev_reopen(). */ - (void) vdev_validate(vd); + if (vd->vdev_aux) { + (void) vdev_validate_aux(vd); + if (vdev_readable(vd) && vdev_writeable(vd) && + !l2arc_vdev_present(vd)) { + uint64_t size = vdev_get_rsize(vd); + l2arc_add_vdev(spa, vd, + VDEV_LABEL_START_SIZE, + size - VDEV_LABEL_START_SIZE); + } + } else { + (void) vdev_validate(vd); + } /* * Reassess parent vdev's health. @@ -1206,22 +1320,27 @@ vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg, int scrub_done) spa_t *spa = vd->vdev_spa; int c; - ASSERT(spa_config_held(spa, RW_WRITER)); + ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER)); if (vd->vdev_children == 0) { mutex_enter(&vd->vdev_dtl_lock); - /* - * We're successfully scrubbed everything up to scrub_txg. - * Therefore, excise all old DTLs up to that point, then - * fold in the DTLs for everything we couldn't scrub. - */ - if (scrub_txg != 0) { + if (scrub_txg != 0 && + (spa->spa_scrub_started || spa->spa_scrub_errors == 0)) { + /* XXX should check scrub_done? */ + /* + * We completed a scrub up to scrub_txg. If we + * did it without rebooting, then the scrub dtl + * will be valid, so excise the old region and + * fold in the scrub dtl. Otherwise, leave the + * dtl as-is if there was an error. + */ space_map_excise(&vd->vdev_dtl_map, 0, scrub_txg); space_map_union(&vd->vdev_dtl_map, &vd->vdev_dtl_scrub); } if (scrub_done) space_map_vacate(&vd->vdev_dtl_scrub, NULL, NULL); mutex_exit(&vd->vdev_dtl_lock); + if (txg != 0) vdev_dirty(vd->vdev_top, VDD_DTL, vd, txg); return; @@ -1291,9 +1410,6 @@ vdev_dtl_sync(vdev_t *vd, uint64_t txg) dmu_buf_t *db; dmu_tx_t *tx; - dprintf("%s in txg %llu pass %d\n", - vdev_description(vd), (u_longlong_t)txg, spa_sync_pass(spa)); - tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg); if (vd->vdev_detached) { @@ -1303,8 +1419,6 @@ vdev_dtl_sync(vdev_t *vd, uint64_t txg) smo->smo_object = 0; } dmu_tx_commit(tx); - dprintf("detach %s committed in txg %llu\n", - vdev_description(vd), txg); return; } @@ -1346,6 +1460,49 @@ vdev_dtl_sync(vdev_t *vd, uint64_t txg) dmu_tx_commit(tx); } +/* + * Determine if resilver is needed, and if so the txg range. + */ +boolean_t +vdev_resilver_needed(vdev_t *vd, uint64_t *minp, uint64_t *maxp) +{ + boolean_t needed = B_FALSE; + uint64_t thismin = UINT64_MAX; + uint64_t thismax = 0; + + if (vd->vdev_children == 0) { + mutex_enter(&vd->vdev_dtl_lock); + if (vd->vdev_dtl_map.sm_space != 0 && vdev_writeable(vd)) { + space_seg_t *ss; + + ss = avl_first(&vd->vdev_dtl_map.sm_root); + thismin = ss->ss_start - 1; + ss = avl_last(&vd->vdev_dtl_map.sm_root); + thismax = ss->ss_end; + needed = B_TRUE; + } + mutex_exit(&vd->vdev_dtl_lock); + } else { + int c; + for (c = 0; c < vd->vdev_children; c++) { + vdev_t *cvd = vd->vdev_child[c]; + uint64_t cmin, cmax; + + if (vdev_resilver_needed(cvd, &cmin, &cmax)) { + thismin = MIN(thismin, cmin); + thismax = MAX(thismax, cmax); + needed = B_TRUE; + } + } + } + + if (needed && minp) { + *minp = thismin; + *maxp = thismax; + } + return (needed); +} + void vdev_load(vdev_t *vd) { @@ -1388,6 +1545,9 @@ vdev_validate_aux(vdev_t *vd) uint64_t guid, version; uint64_t state; + if (!vdev_readable(vd)) + return (0); + if ((label = vdev_label_read_config(vd)) == NULL) { vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN, VDEV_AUX_CORRUPT_DATA); @@ -1418,8 +1578,6 @@ vdev_sync_done(vdev_t *vd, uint64_t txg) { metaslab_t *msp; - dprintf("%s txg %llu\n", vdev_description(vd), txg); - while (msp = txg_list_remove(&vd->vdev_ms_list, TXG_CLEAN(txg))) metaslab_sync_done(msp, txg); } @@ -1432,9 +1590,6 @@ vdev_sync(vdev_t *vd, uint64_t txg) metaslab_t *msp; dmu_tx_t *tx; - dprintf("%s txg %llu pass %d\n", - vdev_description(vd), (u_longlong_t)txg, spa_sync_pass(spa)); - if (vd->vdev_ms_array == 0 && vd->vdev_ms_shift != 0) { ASSERT(vd == vd->vdev_top); tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg); @@ -1462,21 +1617,6 @@ vdev_psize_to_asize(vdev_t *vd, uint64_t psize) return (vd->vdev_ops->vdev_op_asize(vd, psize)); } -const char * -vdev_description(vdev_t *vd) -{ - if (vd == NULL || vd->vdev_ops == NULL) - return (""); - - if (vd->vdev_path != NULL) - return (vd->vdev_path); - - if (vd->vdev_parent == NULL) - return (spa_name(vd->vdev_spa)); - - return (vd->vdev_ops->vdev_op_type); -} - /* * Mark the given vdev faulted. A faulted vdev behaves as if the device could * not be opened, and no I/O is attempted. @@ -1484,43 +1624,29 @@ vdev_description(vdev_t *vd) int vdev_fault(spa_t *spa, uint64_t guid) { - vdev_t *rvd, *vd; - uint64_t txg; + vdev_t *vd; - /* - * Disregard a vdev fault request if the pool has - * experienced a complete failure. - * - * XXX - We do this here so that we don't hold the - * spa_namespace_lock in the event that we can't get - * the RW_WRITER spa_config_lock. - */ - if (spa_state(spa) == POOL_STATE_IO_FAILURE) - return (EIO); + spa_vdev_state_enter(spa); - txg = spa_vdev_enter(spa); + if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) + return (spa_vdev_state_exit(spa, NULL, ENODEV)); - rvd = spa->spa_root_vdev; - - if ((vd = vdev_lookup_by_guid(rvd, guid)) == NULL) - return (spa_vdev_exit(spa, NULL, txg, ENODEV)); if (!vd->vdev_ops->vdev_op_leaf) - return (spa_vdev_exit(spa, NULL, txg, ENOTSUP)); + return (spa_vdev_state_exit(spa, NULL, ENOTSUP)); /* * Faulted state takes precedence over degraded. */ vd->vdev_faulted = 1ULL; vd->vdev_degraded = 0ULL; - vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED, - VDEV_AUX_ERR_EXCEEDED); + vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED, VDEV_AUX_ERR_EXCEEDED); /* - * If marking the vdev as faulted cause the toplevel vdev to become + * If marking the vdev as faulted cause the top-level vdev to become * unavailable, then back off and simply mark the vdev as degraded * instead. */ - if (vdev_is_dead(vd->vdev_top)) { + if (vdev_is_dead(vd->vdev_top) && vd->vdev_aux == NULL) { vd->vdev_degraded = 1ULL; vd->vdev_faulted = 0ULL; @@ -1536,11 +1662,7 @@ vdev_fault(spa_t *spa, uint64_t guid) } } - vdev_config_dirty(vd->vdev_top); - - (void) spa_vdev_exit(spa, NULL, txg, 0); - - return (0); + return (spa_vdev_state_exit(spa, vd, 0)); } /* @@ -1551,46 +1673,28 @@ vdev_fault(spa_t *spa, uint64_t guid) int vdev_degrade(spa_t *spa, uint64_t guid) { - vdev_t *rvd, *vd; - uint64_t txg; + vdev_t *vd; - /* - * Disregard a vdev fault request if the pool has - * experienced a complete failure. - * - * XXX - We do this here so that we don't hold the - * spa_namespace_lock in the event that we can't get - * the RW_WRITER spa_config_lock. - */ - if (spa_state(spa) == POOL_STATE_IO_FAILURE) - return (EIO); + spa_vdev_state_enter(spa); - txg = spa_vdev_enter(spa); + if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) + return (spa_vdev_state_exit(spa, NULL, ENODEV)); - rvd = spa->spa_root_vdev; - - if ((vd = vdev_lookup_by_guid(rvd, guid)) == NULL) - return (spa_vdev_exit(spa, NULL, txg, ENODEV)); if (!vd->vdev_ops->vdev_op_leaf) - return (spa_vdev_exit(spa, NULL, txg, ENOTSUP)); + return (spa_vdev_state_exit(spa, NULL, ENOTSUP)); /* * If the vdev is already faulted, then don't do anything. */ - if (vd->vdev_faulted || vd->vdev_degraded) { - (void) spa_vdev_exit(spa, NULL, txg, 0); - return (0); - } + if (vd->vdev_faulted || vd->vdev_degraded) + return (spa_vdev_state_exit(spa, NULL, 0)); vd->vdev_degraded = 1ULL; if (!vdev_is_dead(vd)) vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_ERR_EXCEEDED); - vdev_config_dirty(vd->vdev_top); - (void) spa_vdev_exit(spa, NULL, txg, 0); - - return (0); + return (spa_vdev_state_exit(spa, vd, 0)); } /* @@ -1600,39 +1704,22 @@ vdev_degrade(spa_t *spa, uint64_t guid) * so no FMA events are generated if the device fails to open. */ int -vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, - vdev_state_t *newstate) +vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate) { - vdev_t *rvd, *vd; - uint64_t txg; + vdev_t *vd; - /* - * Disregard a vdev fault request if the pool has - * experienced a complete failure. - * - * XXX - We do this here so that we don't hold the - * spa_namespace_lock in the event that we can't get - * the RW_WRITER spa_config_lock. - */ - if (spa_state(spa) == POOL_STATE_IO_FAILURE) - return (EIO); + spa_vdev_state_enter(spa); - txg = spa_vdev_enter(spa); - - rvd = spa->spa_root_vdev; - - if ((vd = vdev_lookup_by_guid(rvd, guid)) == NULL) - return (spa_vdev_exit(spa, NULL, txg, ENODEV)); + if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) + return (spa_vdev_state_exit(spa, NULL, ENODEV)); if (!vd->vdev_ops->vdev_op_leaf) - return (spa_vdev_exit(spa, NULL, txg, ENOTSUP)); + return (spa_vdev_state_exit(spa, NULL, ENOTSUP)); vd->vdev_offline = B_FALSE; vd->vdev_tmpoffline = B_FALSE; - vd->vdev_checkremove = (flags & ZFS_ONLINE_CHECKREMOVE) ? - B_TRUE : B_FALSE; - vd->vdev_forcefault = (flags & ZFS_ONLINE_FORCEFAULT) ? - B_TRUE : B_FALSE; + vd->vdev_checkremove = !!(flags & ZFS_ONLINE_CHECKREMOVE); + vd->vdev_forcefault = !!(flags & ZFS_ONLINE_FORCEFAULT); vdev_reopen(vd->vdev_top); vd->vdev_checkremove = vd->vdev_forcefault = B_FALSE; @@ -1644,17 +1731,9 @@ vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vd->vdev_parent->vdev_child[0] == vd) vd->vdev_unspare = B_TRUE; - vdev_config_dirty(vd->vdev_top); + (void) spa_vdev_state_exit(spa, vd, 0); - (void) spa_vdev_exit(spa, NULL, txg, 0); - - /* - * Must hold spa_namespace_lock in order to post resilver sysevent - * w/pool name. - */ - mutex_enter(&spa_namespace_lock); - VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0); - mutex_exit(&spa_namespace_lock); + VERIFY3U(spa_scrub(spa, POOL_SCRUB_RESILVER), ==, 0); return (0); } @@ -1662,29 +1741,15 @@ vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, int vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags) { - vdev_t *rvd, *vd; - uint64_t txg; + vdev_t *vd; - /* - * Disregard a vdev fault request if the pool has - * experienced a complete failure. - * - * XXX - We do this here so that we don't hold the - * spa_namespace_lock in the event that we can't get - * the RW_WRITER spa_config_lock. - */ - if (spa_state(spa) == POOL_STATE_IO_FAILURE) - return (EIO); + spa_vdev_state_enter(spa); - txg = spa_vdev_enter(spa); - - rvd = spa->spa_root_vdev; - - if ((vd = vdev_lookup_by_guid(rvd, guid)) == NULL) - return (spa_vdev_exit(spa, NULL, txg, ENODEV)); + if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) + return (spa_vdev_state_exit(spa, NULL, ENODEV)); if (!vd->vdev_ops->vdev_op_leaf) - return (spa_vdev_exit(spa, NULL, txg, ENOTSUP)); + return (spa_vdev_state_exit(spa, NULL, ENOTSUP)); /* * If the device isn't already offline, try to offline it. @@ -1698,7 +1763,7 @@ vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags) * as long as the remaining devices don't have any DTL holes. */ if (vd->vdev_top->vdev_dtl_map.sm_space != 0) - return (spa_vdev_exit(spa, NULL, txg, EBUSY)); + return (spa_vdev_state_exit(spa, NULL, EBUSY)); /* * Offline this device and reopen its top-level vdev. @@ -1707,105 +1772,111 @@ vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags) */ vd->vdev_offline = B_TRUE; vdev_reopen(vd->vdev_top); - if (vdev_is_dead(vd->vdev_top)) { + if (vdev_is_dead(vd->vdev_top) && vd->vdev_aux == NULL) { vd->vdev_offline = B_FALSE; vdev_reopen(vd->vdev_top); - return (spa_vdev_exit(spa, NULL, txg, EBUSY)); + return (spa_vdev_state_exit(spa, NULL, EBUSY)); } } - vd->vdev_tmpoffline = (flags & ZFS_OFFLINE_TEMPORARY) ? - B_TRUE : B_FALSE; + vd->vdev_tmpoffline = !!(flags & ZFS_OFFLINE_TEMPORARY); - vdev_config_dirty(vd->vdev_top); - - return (spa_vdev_exit(spa, NULL, txg, 0)); + return (spa_vdev_state_exit(spa, vd, 0)); } /* * Clear the error counts associated with this vdev. Unlike vdev_online() and * vdev_offline(), we assume the spa config is locked. We also clear all * children. If 'vd' is NULL, then the user wants to clear all vdevs. - * If reopen is specified then attempt to reopen the vdev if the vdev is - * faulted or degraded. */ void -vdev_clear(spa_t *spa, vdev_t *vd, boolean_t reopen_wanted) +vdev_clear(spa_t *spa, vdev_t *vd) { - int c; + vdev_t *rvd = spa->spa_root_vdev; + + ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL); if (vd == NULL) - vd = spa->spa_root_vdev; + vd = rvd; vd->vdev_stat.vs_read_errors = 0; vd->vdev_stat.vs_write_errors = 0; vd->vdev_stat.vs_checksum_errors = 0; - vd->vdev_is_failing = B_FALSE; - for (c = 0; c < vd->vdev_children; c++) - vdev_clear(spa, vd->vdev_child[c], reopen_wanted); + for (int c = 0; c < vd->vdev_children; c++) + vdev_clear(spa, vd->vdev_child[c]); /* - * If we're in the FAULTED state, then clear the persistent state and - * attempt to reopen the device. We also mark the vdev config dirty, so - * that the new faulted state is written out to disk. + * If we're in the FAULTED state or have experienced failed I/O, then + * clear the persistent state and attempt to reopen the device. We + * also mark the vdev config dirty, so that the new faulted state is + * written out to disk. */ - if (reopen_wanted && (vd->vdev_faulted || vd->vdev_degraded)) { - vd->vdev_faulted = vd->vdev_degraded = 0; - vdev_reopen(vd); - vdev_config_dirty(vd->vdev_top); + if (vd->vdev_faulted || vd->vdev_degraded || + !vdev_readable(vd) || !vdev_writeable(vd)) { - if (vd->vdev_faulted) + vd->vdev_faulted = vd->vdev_degraded = 0; + vd->vdev_cant_read = B_FALSE; + vd->vdev_cant_write = B_FALSE; + + vdev_reopen(vd); + + if (vd != rvd) + vdev_state_dirty(vd->vdev_top); + + if (vd->vdev_aux == NULL && !vdev_is_dead(vd)) spa_async_request(spa, SPA_ASYNC_RESILVER); spa_event_notify(spa, vd, ESC_ZFS_VDEV_CLEAR); } } -int -vdev_readable(vdev_t *vd) -{ - /* XXPOLICY */ - return (!vdev_is_dead(vd)); -} - -int -vdev_writeable(vdev_t *vd) -{ - return (!vdev_is_dead(vd) && !vd->vdev_is_failing); -} - -int +boolean_t vdev_is_dead(vdev_t *vd) { return (vd->vdev_state < VDEV_STATE_DEGRADED); } -int -vdev_error_inject(vdev_t *vd, zio_t *zio) +boolean_t +vdev_readable(vdev_t *vd) { - int error = 0; + return (!vdev_is_dead(vd) && !vd->vdev_cant_read); +} - if (vd->vdev_fault_mode == VDEV_FAULT_NONE) - return (0); +boolean_t +vdev_writeable(vdev_t *vd) +{ + return (!vdev_is_dead(vd) && !vd->vdev_cant_write); +} - if (((1ULL << zio->io_type) & vd->vdev_fault_mask) == 0) - return (0); +boolean_t +vdev_allocatable(vdev_t *vd) +{ + /* + * We currently allow allocations from vdevs which maybe in the + * process of reopening (i.e. VDEV_STATE_CLOSED). If the device + * fails to reopen then we'll catch it later when we're holding + * the proper locks. + */ + return (!(vdev_is_dead(vd) && vd->vdev_state != VDEV_STATE_CLOSED) && + !vd->vdev_cant_write); +} - switch (vd->vdev_fault_mode) { - case VDEV_FAULT_RANDOM: - if (spa_get_random(vd->vdev_fault_arg) == 0) - error = EIO; - break; +boolean_t +vdev_accessible(vdev_t *vd, zio_t *zio) +{ + ASSERT(zio->io_vd == vd); - case VDEV_FAULT_COUNT: - if ((int64_t)--vd->vdev_fault_arg <= 0) - vd->vdev_fault_mode = VDEV_FAULT_NONE; - error = EIO; - break; - } + if (vdev_is_dead(vd) || vd->vdev_remove_wanted) + return (B_FALSE); - return (error); + if (zio->io_type == ZIO_TYPE_READ) + return (!vd->vdev_cant_read); + + if (zio->io_type == ZIO_TYPE_WRITE) + return (!vd->vdev_cant_write); + + return (B_TRUE); } /* @@ -1815,10 +1886,10 @@ void vdev_get_stats(vdev_t *vd, vdev_stat_t *vs) { vdev_t *rvd = vd->vdev_spa->spa_root_vdev; - int c, t; mutex_enter(&vd->vdev_stat_lock); bcopy(&vd->vdev_stat, vs, sizeof (*vs)); + vs->vs_scrub_errors = vd->vdev_spa->spa_scrub_errors; vs->vs_timestamp = gethrtime() - vs->vs_timestamp; vs->vs_state = vd->vdev_state; vs->vs_rsize = vdev_get_rsize(vd); @@ -1829,20 +1900,16 @@ vdev_get_stats(vdev_t *vd, vdev_stat_t *vs) * over all top-level vdevs (i.e. the direct children of the root). */ if (vd == rvd) { - for (c = 0; c < rvd->vdev_children; c++) { + for (int c = 0; c < rvd->vdev_children; c++) { vdev_t *cvd = rvd->vdev_child[c]; vdev_stat_t *cvs = &cvd->vdev_stat; mutex_enter(&vd->vdev_stat_lock); - for (t = 0; t < ZIO_TYPES; t++) { + for (int t = 0; t < ZIO_TYPES; t++) { vs->vs_ops[t] += cvs->vs_ops[t]; vs->vs_bytes[t] += cvs->vs_bytes[t]; } - vs->vs_read_errors += cvs->vs_read_errors; - vs->vs_write_errors += cvs->vs_write_errors; - vs->vs_checksum_errors += cvs->vs_checksum_errors; vs->vs_scrub_examined += cvs->vs_scrub_examined; - vs->vs_scrub_errors += cvs->vs_scrub_errors; mutex_exit(&vd->vdev_stat_lock); } } @@ -1859,29 +1926,54 @@ vdev_clear_stats(vdev_t *vd) } void -vdev_stat_update(zio_t *zio) +vdev_stat_update(zio_t *zio, uint64_t psize) { - vdev_t *vd = zio->io_vd; + vdev_t *rvd = zio->io_spa->spa_root_vdev; + vdev_t *vd = zio->io_vd ? zio->io_vd : rvd; vdev_t *pvd; uint64_t txg = zio->io_txg; vdev_stat_t *vs = &vd->vdev_stat; zio_type_t type = zio->io_type; int flags = zio->io_flags; + /* + * If this i/o is a gang leader, it didn't do any actual work. + */ + if (zio->io_gang_tree) + return; + if (zio->io_error == 0) { + /* + * If this is a root i/o, don't count it -- we've already + * counted the top-level vdevs, and vdev_get_stats() will + * aggregate them when asked. This reduces contention on + * the root vdev_stat_lock and implicitly handles blocks + * that compress away to holes, for which there is no i/o. + * (Holes never create vdev children, so all the counters + * remain zero, which is what we want.) + * + * Note: this only applies to successful i/o (io_error == 0) + * because unlike i/o counts, errors are not additive. + * When reading a ditto block, for example, failure of + * one top-level vdev does not imply a root-level error. + */ + if (vd == rvd) + return; + + ASSERT(vd == zio->io_vd); if (!(flags & ZIO_FLAG_IO_BYPASS)) { mutex_enter(&vd->vdev_stat_lock); vs->vs_ops[type]++; - vs->vs_bytes[type] += zio->io_size; + vs->vs_bytes[type] += psize; mutex_exit(&vd->vdev_stat_lock); } - if ((flags & ZIO_FLAG_IO_REPAIR) && - zio->io_delegate_list == NULL) { + if (flags & ZIO_FLAG_IO_REPAIR) { + ASSERT(zio->io_delegate_list == NULL); mutex_enter(&vd->vdev_stat_lock); if (flags & ZIO_FLAG_SCRUB_THREAD) - vs->vs_scrub_repaired += zio->io_size; + vs->vs_scrub_repaired += psize; else - vs->vs_self_healed += zio->io_size; + vs->vs_self_healed += psize; mutex_exit(&vd->vdev_stat_lock); } return; @@ -1890,22 +1982,18 @@ vdev_stat_update(zio_t *zio) if (flags & ZIO_FLAG_SPECULATIVE) return; - if (vdev_readable(vd)) { - mutex_enter(&vd->vdev_stat_lock); - if (type == ZIO_TYPE_READ) { - if (zio->io_error == ECKSUM) - vs->vs_checksum_errors++; - else - vs->vs_read_errors++; - } - if (type == ZIO_TYPE_WRITE) - vs->vs_write_errors++; - mutex_exit(&vd->vdev_stat_lock); + mutex_enter(&vd->vdev_stat_lock); + if (type == ZIO_TYPE_READ) { + if (zio->io_error == ECKSUM) + vs->vs_checksum_errors++; + else + vs->vs_read_errors++; } + if (type == ZIO_TYPE_WRITE) + vs->vs_write_errors++; + mutex_exit(&vd->vdev_stat_lock); - if (type == ZIO_TYPE_WRITE) { - if (txg == 0 || vd->vdev_children != 0) - return; + if (type == ZIO_TYPE_WRITE && txg != 0 && vd->vdev_children == 0) { if (flags & ZIO_FLAG_SCRUB_THREAD) { ASSERT(flags & ZIO_FLAG_IO_REPAIR); for (pvd = vd; pvd != NULL; pvd = pvd->vdev_parent) @@ -1944,7 +2032,6 @@ vdev_scrub_stat_update(vdev_t *vd, pool_scrub_type_t type, boolean_t complete) vs->vs_scrub_complete = 0; vs->vs_scrub_examined = 0; vs->vs_scrub_repaired = 0; - vs->vs_scrub_errors = 0; vs->vs_scrub_start = gethrestime_sec(); vs->vs_scrub_end = 0; } @@ -2013,13 +2100,53 @@ vdev_config_dirty(vdev_t *vd) int c; /* - * The dirty list is protected by the config lock. The caller must - * either hold the config lock as writer, or must be the sync thread - * (which holds the lock as reader). There's only one sync thread, + * If this is an aux vdev (as with l2cache devices), then we update the + * vdev config manually and set the sync flag. + */ + if (vd->vdev_aux != NULL) { + spa_aux_vdev_t *sav = vd->vdev_aux; + nvlist_t **aux; + uint_t naux; + + for (c = 0; c < sav->sav_count; c++) { + if (sav->sav_vdevs[c] == vd) + break; + } + + if (c == sav->sav_count) { + /* + * We're being removed. There's nothing more to do. + */ + ASSERT(sav->sav_sync == B_TRUE); + return; + } + + sav->sav_sync = B_TRUE; + + VERIFY(nvlist_lookup_nvlist_array(sav->sav_config, + ZPOOL_CONFIG_L2CACHE, &aux, &naux) == 0); + + ASSERT(c < naux); + + /* + * Setting the nvlist in the middle if the array is a little + * sketchy, but it will work. + */ + nvlist_free(aux[c]); + aux[c] = vdev_config_generate(spa, vd, B_TRUE, B_FALSE, B_TRUE); + + return; + } + + /* + * The dirty list is protected by the SCL_CONFIG lock. The caller + * must either hold SCL_CONFIG as writer, or must be the sync thread + * (which holds SCL_CONFIG as reader). There's only one sync thread, * so this is sufficient to ensure mutual exclusion. */ - ASSERT(spa_config_held(spa, RW_WRITER) || - dsl_pool_sync_context(spa_get_dsl(spa))); + ASSERT(spa_config_held(spa, SCL_CONFIG, RW_WRITER) || + (dsl_pool_sync_context(spa_get_dsl(spa)) && + spa_config_held(spa, SCL_CONFIG, RW_READER))); if (vd == rvd) { for (c = 0; c < rvd->vdev_children; c++) @@ -2027,8 +2154,8 @@ vdev_config_dirty(vdev_t *vd) } else { ASSERT(vd == vd->vdev_top); - if (!list_link_active(&vd->vdev_dirty_node)) - list_insert_head(&spa->spa_dirty_list, vd); + if (!list_link_active(&vd->vdev_config_dirty_node)) + list_insert_head(&spa->spa_config_dirty_list, vd); } } @@ -2037,13 +2164,57 @@ vdev_config_clean(vdev_t *vd) { spa_t *spa = vd->vdev_spa; - ASSERT(spa_config_held(spa, RW_WRITER) || - dsl_pool_sync_context(spa_get_dsl(spa))); + ASSERT(spa_config_held(spa, SCL_CONFIG, RW_WRITER) || + (dsl_pool_sync_context(spa_get_dsl(spa)) && + spa_config_held(spa, SCL_CONFIG, RW_READER))); - ASSERT(list_link_active(&vd->vdev_dirty_node)); - list_remove(&spa->spa_dirty_list, vd); + ASSERT(list_link_active(&vd->vdev_config_dirty_node)); + list_remove(&spa->spa_config_dirty_list, vd); } +/* + * Mark a top-level vdev's state as dirty, so that the next pass of + * spa_sync() can convert this into vdev_config_dirty(). We distinguish + * the state changes from larger config changes because they require + * much less locking, and are often needed for administrative actions. + */ +void +vdev_state_dirty(vdev_t *vd) +{ + spa_t *spa = vd->vdev_spa; + + ASSERT(vd == vd->vdev_top); + + /* + * The state list is protected by the SCL_STATE lock. The caller + * must either hold SCL_STATE as writer, or must be the sync thread + * (which holds SCL_STATE as reader). There's only one sync thread, + * so this is sufficient to ensure mutual exclusion. + */ + ASSERT(spa_config_held(spa, SCL_STATE, RW_WRITER) || + (dsl_pool_sync_context(spa_get_dsl(spa)) && + spa_config_held(spa, SCL_STATE, RW_READER))); + + if (!list_link_active(&vd->vdev_state_dirty_node)) + list_insert_head(&spa->spa_state_dirty_list, vd); +} + +void +vdev_state_clean(vdev_t *vd) +{ + spa_t *spa = vd->vdev_spa; + + ASSERT(spa_config_held(spa, SCL_STATE, RW_WRITER) || + (dsl_pool_sync_context(spa_get_dsl(spa)) && + spa_config_held(spa, SCL_STATE, RW_READER))); + + ASSERT(list_link_active(&vd->vdev_state_dirty_node)); + list_remove(&spa->spa_state_dirty_list, vd); +} + +/* + * Propagate vdev state up from children to parent. + */ void vdev_propagate_state(vdev_t *vd) { @@ -2056,10 +2227,21 @@ vdev_propagate_state(vdev_t *vd) if (vd->vdev_children > 0) { for (c = 0; c < vd->vdev_children; c++) { child = vd->vdev_child[c]; - if (vdev_is_dead(child) && !vdev_readable(child)) - faulted++; - else if (child->vdev_state <= VDEV_STATE_DEGRADED) + + if (!vdev_readable(child) || + (!vdev_writeable(child) && (spa_mode & FWRITE))) { + /* + * Root special: if there is a top-level log + * device, treat the root vdev as if it were + * degraded. + */ + if (child->vdev_islog && vd == rvd) + degraded++; + else + faulted++; + } else if (child->vdev_state <= VDEV_STATE_DEGRADED) { degraded++; + } if (child->vdev_stat.vs_aux == VDEV_AUX_CORRUPT_DATA) corrupted++; @@ -2068,7 +2250,7 @@ vdev_propagate_state(vdev_t *vd) vd->vdev_ops->vdev_op_state_change(vd, faulted, degraded); /* - * Root special: if there is a toplevel vdev that cannot be + * Root special: if there is a top-level vdev that cannot be * opened due to corrupted metadata, then propagate the root * vdev's aux state as 'corrupt' rather than 'insufficient * replicas'. @@ -2079,7 +2261,7 @@ vdev_propagate_state(vdev_t *vd) VDEV_AUX_CORRUPT_DATA); } - if (vd->vdev_parent && !vd->vdev_islog) + if (vd->vdev_parent) vdev_propagate_state(vd->vdev_parent); } @@ -2095,6 +2277,7 @@ void vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) { uint64_t save_state; + spa_t *spa = vd->vdev_spa; if (state == vd->vdev_state) { vd->vdev_stat.vs_aux = aux; @@ -2114,7 +2297,7 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) * want here. This is limited to leaf devices, because otherwise * closing the device will affect other children. */ - if (!vdev_readable(vd) && vd->vdev_ops->vdev_op_leaf) + if (vdev_is_dead(vd) && vd->vdev_ops->vdev_op_leaf) vd->vdev_ops->vdev_op_close(vd); if (vd->vdev_removed && @@ -2136,7 +2319,7 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) * Indicate to the ZFS DE that this device has been removed, and * any recent errors should be ignored. */ - zfs_post_remove(vd->vdev_spa, vd); + zfs_post_remove(spa, vd); vd->vdev_removed = B_TRUE; } else if (state == VDEV_STATE_CANT_OPEN) { /* @@ -2145,7 +2328,8 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) * begin with. Failure to open such a device is not considered * an error. */ - if (vd->vdev_spa->spa_load_state == SPA_LOAD_IMPORT && + if (spa->spa_load_state == SPA_LOAD_IMPORT && + !spa->spa_import_faulted && vd->vdev_ops->vdev_op_leaf) vd->vdev_not_present = 1; @@ -2166,7 +2350,7 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) */ if ((vd->vdev_prevstate != state || vd->vdev_forcefault) && !vd->vdev_not_present && !vd->vdev_checkremove && - vd != vd->vdev_spa->spa_root_vdev) { + vd != spa->spa_root_vdev) { const char *class; switch (aux) { @@ -2188,12 +2372,14 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) case VDEV_AUX_BAD_LABEL: class = FM_EREPORT_ZFS_DEVICE_BAD_LABEL; break; + case VDEV_AUX_IO_FAILURE: + class = FM_EREPORT_ZFS_IO_FAILURE; + break; default: class = FM_EREPORT_ZFS_DEVICE_UNKNOWN; } - zfs_ereport_post(class, vd->vdev_spa, - vd, NULL, save_state, 0); + zfs_ereport_post(class, spa, vd, NULL, save_state, 0); } /* Erase any notion of persistent removed state */ @@ -2205,3 +2391,35 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) if (!isopen) vdev_propagate_state(vd); } + +/* + * Check the vdev configuration to ensure that it's capable of supporting + * a root pool. Currently, we do not support RAID-Z or partial configuration. + * In addition, only a single top-level vdev is allowed and none of the leaves + * can be wholedisks. + */ +boolean_t +vdev_is_bootable(vdev_t *vd) +{ + int c; + + if (!vd->vdev_ops->vdev_op_leaf) { + char *vdev_type = vd->vdev_ops->vdev_op_type; + + if (strcmp(vdev_type, VDEV_TYPE_ROOT) == 0 && + vd->vdev_children > 1) { + return (B_FALSE); + } else if (strcmp(vdev_type, VDEV_TYPE_RAIDZ) == 0 || + strcmp(vdev_type, VDEV_TYPE_MISSING) == 0) { + return (B_FALSE); + } + } else if (vd->vdev_wholedisk == 1) { + return (B_FALSE); + } + + for (c = 0; c < vd->vdev_children; c++) { + if (!vdev_is_bootable(vd->vdev_child[c])) + return (B_FALSE); + } + return (B_TRUE); +} diff --git a/zfs/lib/libzpool/vdev_cache.c b/zfs/lib/libzpool/vdev_cache.c index 370e8a890..5a7b59f6e 100644 --- a/zfs/lib/libzpool/vdev_cache.c +++ b/zfs/lib/libzpool/vdev_cache.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)vdev_cache.c 1.7 08/01/10 SMI" - #include #include #include @@ -136,10 +134,6 @@ vdev_cache_evict(vdev_cache_t *vc, vdev_cache_entry_t *ve) ASSERT(ve->ve_fill_io == NULL); ASSERT(ve->ve_data != NULL); - dprintf("evicting %p, off %llx, LRU %llu, age %lu, hits %u, stale %u\n", - vc, ve->ve_offset, ve->ve_lastused, lbolt - ve->ve_lastused, - ve->ve_hits, ve->ve_missed_update); - avl_remove(&vc->vc_lastused_tree, ve); avl_remove(&vc->vc_offset_tree, ve); zio_buf_free(ve->ve_data, VCBS); @@ -170,10 +164,8 @@ vdev_cache_allocate(zio_t *zio) if ((avl_numnodes(&vc->vc_lastused_tree) << zfs_vdev_cache_bshift) > zfs_vdev_cache_size) { ve = avl_first(&vc->vc_lastused_tree); - if (ve->ve_fill_io != NULL) { - dprintf("can't evict in %p, still filling\n", vc); + if (ve->ve_fill_io != NULL) return (NULL); - } ASSERT(ve->ve_hits != 0); vdev_cache_evict(vc, ve); } @@ -275,7 +267,7 @@ vdev_cache_read(zio_t *zio) /* * If the I/O straddles two or more cache blocks, don't cache it. */ - if (P2CROSS(zio->io_offset, zio->io_offset + zio->io_size - 1, VCBS)) + if (P2BOUNDARY(zio->io_offset, zio->io_size, VCBS)) return (EXDEV); ASSERT(cache_phase + zio->io_size <= VCBS); @@ -316,11 +308,9 @@ vdev_cache_read(zio_t *zio) return (ENOMEM); } - fio = zio_vdev_child_io(zio, NULL, zio->io_vd, cache_offset, + fio = zio_vdev_delegated_io(zio->io_vd, cache_offset, ve->ve_data, VCBS, ZIO_TYPE_READ, ZIO_PRIORITY_CACHE_FILL, - ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_PROPAGATE | - ZIO_FLAG_DONT_RETRY | ZIO_FLAG_NOBOOKMARK, - vdev_cache_fill, ve); + ZIO_FLAG_DONT_CACHE, vdev_cache_fill, ve); ve->ve_fill_io = fio; fio->io_delegate_list = zio; diff --git a/zfs/lib/libzpool/vdev_disk.c b/zfs/lib/libzpool/vdev_disk.c deleted file mode 100644 index 5f73c9aa2..000000000 --- a/zfs/lib/libzpool/vdev_disk.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "@(#)vdev_disk.c 1.15 08/04/09 SMI" - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Virtual device vector for disks. - */ - -extern ldi_ident_t zfs_li; - -typedef struct vdev_disk_buf { - buf_t vdb_buf; - zio_t *vdb_io; -} vdev_disk_buf_t; - -static int -vdev_disk_open_common(vdev_t *vd) -{ - vdev_disk_t *dvd; - dev_t dev; - int error; - - /* - * We must have a pathname, and it must be absolute. - */ - if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') { - vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; - return (EINVAL); - } - - dvd = vd->vdev_tsd = kmem_zalloc(sizeof (vdev_disk_t), KM_SLEEP); - - /* - * When opening a disk device, we want to preserve the user's original - * intent. We always want to open the device by the path the user gave - * us, even if it is one of multiple paths to the save device. But we - * also want to be able to survive disks being removed/recabled. - * Therefore the sequence of opening devices is: - * - * 1. Try opening the device by path. For legacy pools without the - * 'whole_disk' property, attempt to fix the path by appending 's0'. - * - * 2. If the devid of the device matches the stored value, return - * success. - * - * 3. Otherwise, the device may have moved. Try opening the device - * by the devid instead. - * - */ - if (vd->vdev_devid != NULL) { - if (ddi_devid_str_decode(vd->vdev_devid, &dvd->vd_devid, - &dvd->vd_minor) != 0) { - vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; - return (EINVAL); - } - } - - error = EINVAL; /* presume failure */ - - if (vd->vdev_path != NULL) { - ddi_devid_t devid; - - if (vd->vdev_wholedisk == -1ULL) { - size_t len = strlen(vd->vdev_path) + 3; - char *buf = kmem_alloc(len, KM_SLEEP); - ldi_handle_t lh; - - (void) snprintf(buf, len, "%ss0", vd->vdev_path); - - if (ldi_open_by_name(buf, spa_mode, kcred, - &lh, zfs_li) == 0) { - spa_strfree(vd->vdev_path); - vd->vdev_path = buf; - vd->vdev_wholedisk = 1ULL; - (void) ldi_close(lh, spa_mode, kcred); - } else { - kmem_free(buf, len); - } - } - - error = ldi_open_by_name(vd->vdev_path, spa_mode, kcred, - &dvd->vd_lh, zfs_li); - - /* - * Compare the devid to the stored value. - */ - if (error == 0 && vd->vdev_devid != NULL && - ldi_get_devid(dvd->vd_lh, &devid) == 0) { - if (ddi_devid_compare(devid, dvd->vd_devid) != 0) { - error = EINVAL; - (void) ldi_close(dvd->vd_lh, spa_mode, kcred); - dvd->vd_lh = NULL; - } - ddi_devid_free(devid); - } - - /* - * If we succeeded in opening the device, but 'vdev_wholedisk' - * is not yet set, then this must be a slice. - */ - if (error == 0 && vd->vdev_wholedisk == -1ULL) - vd->vdev_wholedisk = 0; - } - - /* - * If we were unable to open by path, or the devid check fails, open by - * devid instead. - */ - if (error != 0 && vd->vdev_devid != NULL) - error = ldi_open_by_devid(dvd->vd_devid, dvd->vd_minor, - spa_mode, kcred, &dvd->vd_lh, zfs_li); - - /* - * If all else fails, then try opening by physical path (if available) - * or the logical path (if we failed due to the devid check). While not - * as reliable as the devid, this will give us something, and the higher - * level vdev validation will prevent us from opening the wrong device. - */ - if (error) { - if (vd->vdev_physpath != NULL && - (dev = ddi_pathname_to_dev_t(vd->vdev_physpath)) != ENODEV) - error = ldi_open_by_dev(&dev, OTYP_BLK, spa_mode, - kcred, &dvd->vd_lh, zfs_li); - - /* - * Note that we don't support the legacy auto-wholedisk support - * as above. This hasn't been used in a very long time and we - * don't need to propagate its oddities to this edge condition. - */ - if (error && vd->vdev_path != NULL) - error = ldi_open_by_name(vd->vdev_path, spa_mode, kcred, - &dvd->vd_lh, zfs_li); - } - - if (error) - vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; - - return (error); -} - -static int -vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) -{ - vdev_disk_t *dvd; - struct dk_minfo dkm; - int error; - dev_t dev; - int otyp; - - error = vdev_disk_open_common(vd); - if (error) - return (error); - - dvd = vd->vdev_tsd; - /* - * Once a device is opened, verify that the physical device path (if - * available) is up to date. - */ - if (ldi_get_dev(dvd->vd_lh, &dev) == 0 && - ldi_get_otyp(dvd->vd_lh, &otyp) == 0) { - char *physpath, *minorname; - - physpath = kmem_alloc(MAXPATHLEN, KM_SLEEP); - minorname = NULL; - if (ddi_dev_pathname(dev, otyp, physpath) == 0 && - ldi_get_minor_name(dvd->vd_lh, &minorname) == 0 && - (vd->vdev_physpath == NULL || - strcmp(vd->vdev_physpath, physpath) != 0)) { - if (vd->vdev_physpath) - spa_strfree(vd->vdev_physpath); - (void) strlcat(physpath, ":", MAXPATHLEN); - (void) strlcat(physpath, minorname, MAXPATHLEN); - vd->vdev_physpath = spa_strdup(physpath); - } - if (minorname) - kmem_free(minorname, strlen(minorname) + 1); - kmem_free(physpath, MAXPATHLEN); - } - - /* - * Determine the actual size of the device. - */ - if (ldi_get_size(dvd->vd_lh, psize) != 0) { - vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; - return (EINVAL); - } - - /* - * If we own the whole disk, try to enable disk write caching. - * We ignore errors because it's OK if we can't do it. - */ - if (vd->vdev_wholedisk == 1) { - int wce = 1; - (void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce, - FKIOCTL, kcred, NULL); - } - - /* - * Determine the device's minimum transfer size. - * If the ioctl isn't supported, assume DEV_BSIZE. - */ - if (ldi_ioctl(dvd->vd_lh, DKIOCGMEDIAINFO, (intptr_t)&dkm, - FKIOCTL, kcred, NULL) != 0) - dkm.dki_lbsize = DEV_BSIZE; - - *ashift = highbit(MAX(dkm.dki_lbsize, SPA_MINBLOCKSIZE)) - 1; - - /* - * Clear the nowritecache bit, so that on a vdev_reopen() we will - * try again. - */ - vd->vdev_nowritecache = B_FALSE; - - return (0); -} - -static void -vdev_disk_close(vdev_t *vd) -{ - vdev_disk_t *dvd = vd->vdev_tsd; - - if (dvd == NULL) - return; - - if (dvd->vd_minor != NULL) - ddi_devid_str_free(dvd->vd_minor); - - if (dvd->vd_devid != NULL) - ddi_devid_free(dvd->vd_devid); - - if (dvd->vd_lh != NULL) - (void) ldi_close(dvd->vd_lh, spa_mode, kcred); - - kmem_free(dvd, sizeof (vdev_disk_t)); - vd->vdev_tsd = NULL; -} - -int -vdev_disk_physio(ldi_handle_t vd_lh, caddr_t data, size_t size, - uint64_t offset, int flags) -{ - buf_t *bp; - int error = 0; - - if (vd_lh == NULL) - return (EINVAL); - - ASSERT(flags & B_READ || flags & B_WRITE); - - bp = getrbuf(KM_SLEEP); - bp->b_flags = flags | B_BUSY | B_NOCACHE | B_FAILFAST; - bp->b_bcount = size; - bp->b_un.b_addr = (void *)data; - bp->b_lblkno = lbtodb(offset); - bp->b_bufsize = size; - - error = ldi_strategy(vd_lh, bp); - ASSERT(error == 0); - if ((error = biowait(bp)) == 0 && bp->b_resid != 0) - error = EIO; - freerbuf(bp); - - return (error); -} - -static int -vdev_disk_probe_io(vdev_t *vd, caddr_t data, size_t size, uint64_t offset, - int flags) -{ - int error = 0; - vdev_disk_t *dvd = vd->vdev_tsd; - - if (vd == NULL || dvd == NULL || dvd->vd_lh == NULL) - return (EINVAL); - - error = vdev_disk_physio(dvd->vd_lh, data, size, offset, flags); - - if (zio_injection_enabled && error == 0) - error = zio_handle_device_injection(vd, EIO); - - return (error); -} - -/* - * Determine if the underlying device is accessible by reading and writing - * to a known location. We must be able to do this during syncing context - * and thus we cannot set the vdev state directly. - */ -static int -vdev_disk_probe(vdev_t *vd) -{ - uint64_t offset; - vdev_t *nvd; - int l, error = 0, retries = 0; - char *vl_pad; - - if (vd == NULL) - return (EINVAL); - - /* Hijack the current vdev */ - nvd = vd; - - /* - * Pick a random label to rewrite. - */ - l = spa_get_random(VDEV_LABELS); - ASSERT(l < VDEV_LABELS); - - offset = vdev_label_offset(vd->vdev_psize, l, - offsetof(vdev_label_t, vl_pad)); - - vl_pad = kmem_alloc(VDEV_SKIP_SIZE, KM_SLEEP); - - /* - * Try to read and write to a special location on the - * label. We use the existing vdev initially and only - * try to create and reopen it if we encounter a failure. - */ - while ((error = vdev_disk_probe_io(nvd, vl_pad, VDEV_SKIP_SIZE, - offset, B_READ)) != 0 && retries == 0) { - - nvd = kmem_zalloc(sizeof (vdev_t), KM_SLEEP); - if (vd->vdev_path) - nvd->vdev_path = spa_strdup(vd->vdev_path); - if (vd->vdev_physpath) - nvd->vdev_physpath = spa_strdup(vd->vdev_physpath); - if (vd->vdev_devid) - nvd->vdev_devid = spa_strdup(vd->vdev_devid); - nvd->vdev_wholedisk = vd->vdev_wholedisk; - nvd->vdev_guid = vd->vdev_guid; - retries++; - - error = vdev_disk_open_common(nvd); - if (error) - break; - } - - if (!error) { - error = vdev_disk_probe_io(nvd, vl_pad, VDEV_SKIP_SIZE, - offset, B_WRITE); - } - - /* Clean up if we allocated a new vdev */ - if (retries) { - vdev_disk_close(nvd); - if (nvd->vdev_path) - spa_strfree(nvd->vdev_path); - if (nvd->vdev_physpath) - spa_strfree(nvd->vdev_physpath); - if (nvd->vdev_devid) - spa_strfree(nvd->vdev_devid); - kmem_free(nvd, sizeof (vdev_t)); - } - kmem_free(vl_pad, VDEV_SKIP_SIZE); - - /* Reset the failing flag */ - if (!error) - vd->vdev_is_failing = B_FALSE; - - return (error); -} - -static void -vdev_disk_io_intr(buf_t *bp) -{ - vdev_disk_buf_t *vdb = (vdev_disk_buf_t *)bp; - zio_t *zio = vdb->vdb_io; - - if ((zio->io_error = geterror(bp)) == 0 && bp->b_resid != 0) - zio->io_error = EIO; - - kmem_free(vdb, sizeof (vdev_disk_buf_t)); - - zio_interrupt(zio); -} - -static void -vdev_disk_ioctl_done(void *zio_arg, int error) -{ - zio_t *zio = zio_arg; - - zio->io_error = error; - - zio_interrupt(zio); -} - -static int -vdev_disk_io_start(zio_t *zio) -{ - vdev_t *vd = zio->io_vd; - vdev_disk_t *dvd = vd->vdev_tsd; - vdev_disk_buf_t *vdb; - buf_t *bp; - int flags, error; - - if (zio->io_type == ZIO_TYPE_IOCTL) { - zio_vdev_io_bypass(zio); - - /* XXPOLICY */ - if (!vdev_readable(vd)) { - zio->io_error = ENXIO; - return (ZIO_PIPELINE_CONTINUE); - } - - switch (zio->io_cmd) { - - case DKIOCFLUSHWRITECACHE: - - if (zfs_nocacheflush) - break; - - if (vd->vdev_nowritecache) { - zio->io_error = ENOTSUP; - break; - } - - zio->io_dk_callback.dkc_callback = vdev_disk_ioctl_done; - zio->io_dk_callback.dkc_flag = FLUSH_VOLATILE; - zio->io_dk_callback.dkc_cookie = zio; - - error = ldi_ioctl(dvd->vd_lh, zio->io_cmd, - (uintptr_t)&zio->io_dk_callback, - FKIOCTL, kcred, NULL); - - if (error == 0) { - /* - * The ioctl will be done asychronously, - * and will call vdev_disk_ioctl_done() - * upon completion. - */ - return (ZIO_PIPELINE_STOP); - } - - if (error == ENOTSUP || error == ENOTTY) { - /* - * If we get ENOTSUP or ENOTTY, we know that - * no future attempts will ever succeed. - * In this case we set a persistent bit so - * that we don't bother with the ioctl in the - * future. - */ - vd->vdev_nowritecache = B_TRUE; - } - zio->io_error = error; - - break; - - default: - zio->io_error = ENOTSUP; - } - - return (ZIO_PIPELINE_CONTINUE); - } - - if (zio->io_type == ZIO_TYPE_READ && vdev_cache_read(zio) == 0) - return (ZIO_PIPELINE_STOP); - - if ((zio = vdev_queue_io(zio)) == NULL) - return (ZIO_PIPELINE_STOP); - - if (zio->io_type == ZIO_TYPE_WRITE) - error = vdev_writeable(vd) ? vdev_error_inject(vd, zio) : ENXIO; - else - error = vdev_readable(vd) ? vdev_error_inject(vd, zio) : ENXIO; - error = (vd->vdev_remove_wanted || vd->vdev_is_failing) ? ENXIO : error; - - if (error) { - zio->io_error = error; - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); - } - - flags = (zio->io_type == ZIO_TYPE_READ ? B_READ : B_WRITE); - flags |= B_BUSY | B_NOCACHE; - if (zio->io_flags & ZIO_FLAG_FAILFAST) - flags |= B_FAILFAST; - - vdb = kmem_alloc(sizeof (vdev_disk_buf_t), KM_SLEEP); - - vdb->vdb_io = zio; - bp = &vdb->vdb_buf; - - bioinit(bp); - bp->b_flags = flags; - bp->b_bcount = zio->io_size; - bp->b_un.b_addr = zio->io_data; - bp->b_lblkno = lbtodb(zio->io_offset); - bp->b_bufsize = zio->io_size; - bp->b_iodone = (int (*)())vdev_disk_io_intr; - - error = ldi_strategy(dvd->vd_lh, bp); - /* ldi_strategy() will return non-zero only on programming errors */ - ASSERT(error == 0); - - return (ZIO_PIPELINE_STOP); -} - -static int -vdev_disk_io_done(zio_t *zio) -{ - vdev_queue_io_done(zio); - - if (zio->io_type == ZIO_TYPE_WRITE) - vdev_cache_write(zio); - - if (zio_injection_enabled && zio->io_error == 0) - zio->io_error = zio_handle_device_injection(zio->io_vd, EIO); - - /* - * If the device returned EIO, then attempt a DKIOCSTATE ioctl to see if - * the device has been removed. If this is the case, then we trigger an - * asynchronous removal of the device. Otherwise, probe the device and - * make sure it's still accessible. - */ - if (zio->io_error == EIO) { - vdev_t *vd = zio->io_vd; - vdev_disk_t *dvd = vd->vdev_tsd; - int state; - - state = DKIO_NONE; - if (dvd && ldi_ioctl(dvd->vd_lh, DKIOCSTATE, (intptr_t)&state, - FKIOCTL, kcred, NULL) == 0 && - state != DKIO_INSERTED) { - vd->vdev_remove_wanted = B_TRUE; - spa_async_request(zio->io_spa, SPA_ASYNC_REMOVE); - } else if (vdev_probe(vd) != 0) { - ASSERT(vd->vdev_ops->vdev_op_leaf); - vd->vdev_is_failing = B_TRUE; - } - } - - return (ZIO_PIPELINE_CONTINUE); -} - -vdev_ops_t vdev_disk_ops = { - vdev_disk_open, - vdev_disk_close, - vdev_disk_probe, - vdev_default_asize, - vdev_disk_io_start, - vdev_disk_io_done, - NULL, - VDEV_TYPE_DISK, /* name of this vdev type */ - B_TRUE /* leaf vdev */ -}; - -/* - * Given the root disk device pathname, read the label from the device, - * and construct a configuration nvlist. - */ -nvlist_t * -vdev_disk_read_rootlabel(char *devpath) -{ - nvlist_t *config = NULL; - ldi_handle_t vd_lh; - vdev_label_t *label; - uint64_t s, size; - int l; - - /* - * Read the device label and build the nvlist. - */ - if (ldi_open_by_name(devpath, FREAD, kcred, &vd_lh, zfs_li)) - return (NULL); - - if (ldi_get_size(vd_lh, &s)) - return (NULL); - - size = P2ALIGN_TYPED(s, sizeof (vdev_label_t), uint64_t); - label = kmem_alloc(sizeof (vdev_label_t), KM_SLEEP); - - for (l = 0; l < VDEV_LABELS; l++) { - uint64_t offset, state, txg = 0; - - /* read vdev label */ - offset = vdev_label_offset(size, l, 0); - if (vdev_disk_physio(vd_lh, (caddr_t)label, - VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE + - VDEV_PHYS_SIZE, offset, B_READ) != 0) - continue; - - if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist, - sizeof (label->vl_vdev_phys.vp_nvlist), &config, 0) != 0) { - config = NULL; - continue; - } - - if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, - &state) != 0 || state >= POOL_STATE_DESTROYED) { - nvlist_free(config); - config = NULL; - continue; - } - - if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, - &txg) != 0 || txg == 0) { - nvlist_free(config); - config = NULL; - continue; - } - - break; - } - - kmem_free(label, sizeof (vdev_label_t)); - return (config); -} diff --git a/zfs/lib/libzpool/vdev_file.c b/zfs/lib/libzpool/vdev_file.c index 974c4cdab..dc0e920bf 100644 --- a/zfs/lib/libzpool/vdev_file.c +++ b/zfs/lib/libzpool/vdev_file.c @@ -19,28 +19,28 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)vdev_file.c 1.7 07/11/27 SMI" - #include #include #include #include #include #include +#include /* * Virtual device vector for files. */ static int -vdev_file_open_common(vdev_t *vd) +vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) { vdev_file_t *vf; vnode_t *vp; + vattr_t vattr; int error; /* @@ -79,22 +79,6 @@ vdev_file_open_common(vdev_t *vd) return (ENODEV); } #endif - - return (0); -} - -static int -vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) -{ - vdev_file_t *vf; - vattr_t vattr; - int error; - - if ((error = vdev_file_open_common(vd)) != 0) - return (error); - - vf = vd->vdev_tsd; - /* * Determine the physical size of the file. */ @@ -129,103 +113,14 @@ vdev_file_close(vdev_t *vd) vd->vdev_tsd = NULL; } -static int -vdev_file_probe_io(vdev_t *vd, caddr_t data, size_t size, uint64_t offset, - enum uio_rw rw) -{ - vdev_file_t *vf = vd->vdev_tsd; - ssize_t resid; - int error = 0; - - if (vd == NULL || vf == NULL || vf->vf_vnode == NULL) - return (EINVAL); - - ASSERT(rw == UIO_READ || rw == UIO_WRITE); - - error = vn_rdwr(rw, vf->vf_vnode, data, size, offset, UIO_SYSSPACE, - 0, RLIM64_INFINITY, kcred, &resid); - if (error || resid != 0) - return (EIO); - return (0); -} - -/* - * Determine if the underlying device is accessible by reading and writing - * to a known location. We must be able to do this during syncing context - * and thus we cannot set the vdev state directly. - */ -static int -vdev_file_probe(vdev_t *vd) -{ - vdev_t *nvd; - char *vl_boot; - uint64_t offset; - int l, error = 0, retries = 0; - - if (vd == NULL) - return (EINVAL); - - /* Hijack the current vdev */ - nvd = vd; - - /* - * Pick a random label to rewrite. - */ - l = spa_get_random(VDEV_LABELS); - ASSERT(l < VDEV_LABELS); - - offset = vdev_label_offset(vd->vdev_psize, l, - offsetof(vdev_label_t, vl_boot_header)); - - vl_boot = kmem_alloc(VDEV_BOOT_HEADER_SIZE, KM_SLEEP); - - while ((error = vdev_file_probe_io(nvd, vl_boot, VDEV_BOOT_HEADER_SIZE, - offset, UIO_READ)) != 0 && retries == 0) { - - /* - * If we failed with the vdev that was passed in then - * try allocating a new one and try again. - */ - nvd = kmem_zalloc(sizeof (vdev_t), KM_SLEEP); - if (vd->vdev_path) - nvd->vdev_path = spa_strdup(vd->vdev_path); - retries++; - - error = vdev_file_open_common(nvd); - if (error) - break; - } - - if ((spa_mode & FWRITE) && !error) { - error = vdev_file_probe_io(nvd, vl_boot, VDEV_BOOT_HEADER_SIZE, - offset, UIO_WRITE); - } - - if (retries) { - vdev_file_close(nvd); - if (nvd->vdev_path) - spa_strfree(nvd->vdev_path); - kmem_free(nvd, sizeof (vdev_t)); - } - kmem_free(vl_boot, VDEV_BOOT_HEADER_SIZE); - - if (!error) - vd->vdev_is_failing = B_FALSE; - - return (error); -} - static int vdev_file_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; vdev_file_t *vf = vd->vdev_tsd; ssize_t resid; - int error; if (zio->io_type == ZIO_TYPE_IOCTL) { - zio_vdev_io_bypass(zio); - /* XXPOLICY */ if (!vdev_readable(vd)) { zio->io_error = ENXIO; @@ -236,8 +131,6 @@ vdev_file_io_start(zio_t *zio) case DKIOCFLUSHWRITECACHE: zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC, kcred, NULL); - dprintf("fsync(%s) = %d\n", vdev_description(vd), - zio->io_error); break; default: zio->io_error = ENOTSUP; @@ -246,30 +139,6 @@ vdev_file_io_start(zio_t *zio) return (ZIO_PIPELINE_CONTINUE); } - /* - * In the kernel, don't bother double-caching, but in userland, - * we want to test the vdev_cache code. - */ -#ifndef _KERNEL - if (zio->io_type == ZIO_TYPE_READ && vdev_cache_read(zio) == 0) - return (ZIO_PIPELINE_STOP); -#endif - - if ((zio = vdev_queue_io(zio)) == NULL) - return (ZIO_PIPELINE_STOP); - - /* XXPOLICY */ - if (zio->io_type == ZIO_TYPE_WRITE) - error = vdev_writeable(vd) ? vdev_error_inject(vd, zio) : ENXIO; - else - error = vdev_readable(vd) ? vdev_error_inject(vd, zio) : ENXIO; - error = (vd->vdev_remove_wanted || vd->vdev_is_failing) ? ENXIO : error; - if (error) { - zio->io_error = error; - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); - } - zio->io_error = vn_rdwr(zio->io_type == ZIO_TYPE_READ ? UIO_READ : UIO_WRITE, vf->vf_vnode, zio->io_data, zio->io_size, zio->io_offset, UIO_SYSSPACE, @@ -283,35 +152,15 @@ vdev_file_io_start(zio_t *zio) return (ZIO_PIPELINE_STOP); } -static int +/* ARGSUSED */ +static void vdev_file_io_done(zio_t *zio) { - vdev_t *vd = zio->io_vd; - - if (zio_injection_enabled && zio->io_error == 0) - zio->io_error = zio_handle_device_injection(vd, EIO); - - /* - * If an error has been encountered then attempt to probe the device - * to determine if it's still accessible. - */ - if (zio->io_error == EIO && vdev_probe(vd) != 0) - vd->vdev_is_failing = B_TRUE; - - vdev_queue_io_done(zio); - -#ifndef _KERNEL - if (zio->io_type == ZIO_TYPE_WRITE) - vdev_cache_write(zio); -#endif - - return (ZIO_PIPELINE_CONTINUE); } vdev_ops_t vdev_file_ops = { vdev_file_open, vdev_file_close, - vdev_file_probe, vdev_default_asize, vdev_file_io_start, vdev_file_io_done, @@ -328,7 +177,6 @@ vdev_ops_t vdev_file_ops = { vdev_ops_t vdev_disk_ops = { vdev_file_open, vdev_file_close, - vdev_file_probe, vdev_default_asize, vdev_file_io_start, vdev_file_io_done, diff --git a/zfs/lib/libzpool/vdev_label.c b/zfs/lib/libzpool/vdev_label.c index 7dcf1facd..bf930466f 100644 --- a/zfs/lib/libzpool/vdev_label.c +++ b/zfs/lib/libzpool/vdev_label.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)vdev_label.c 1.18 07/12/12 SMI" - /* * Virtual Device Labels * --------------------- @@ -159,25 +157,45 @@ vdev_label_offset(uint64_t psize, int l, uint64_t offset) 0 : psize - VDEV_LABELS * sizeof (vdev_label_t))); } +/* + * Returns back the vdev label associated with the passed in offset. + */ +int +vdev_label_number(uint64_t psize, uint64_t offset) +{ + int l; + + if (offset >= psize - VDEV_LABEL_END_SIZE) { + offset -= psize - VDEV_LABEL_END_SIZE; + offset += (VDEV_LABELS / 2) * sizeof (vdev_label_t); + } + l = offset / sizeof (vdev_label_t); + return (l < VDEV_LABELS ? l : -1); +} + static void vdev_label_read(zio_t *zio, vdev_t *vd, int l, void *buf, uint64_t offset, - uint64_t size, zio_done_func_t *done, void *private) + uint64_t size, zio_done_func_t *done, void *private, int flags) { - ASSERT(vd->vdev_children == 0); + ASSERT(spa_config_held(zio->io_spa, SCL_STATE_ALL, RW_WRITER) == + SCL_STATE_ALL); + ASSERT(flags & ZIO_FLAG_CONFIG_WRITER); zio_nowait(zio_read_phys(zio, vd, vdev_label_offset(vd->vdev_psize, l, offset), size, buf, ZIO_CHECKSUM_LABEL, done, private, - ZIO_PRIORITY_SYNC_READ, - ZIO_FLAG_CONFIG_HELD | ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE, - B_TRUE)); + ZIO_PRIORITY_SYNC_READ, flags, B_TRUE)); } static void vdev_label_write(zio_t *zio, vdev_t *vd, int l, void *buf, uint64_t offset, uint64_t size, zio_done_func_t *done, void *private, int flags) { - ASSERT(vd->vdev_children == 0); + ASSERT(spa_config_held(zio->io_spa, SCL_ALL, RW_WRITER) == SCL_ALL || + (spa_config_held(zio->io_spa, SCL_CONFIG | SCL_STATE, RW_READER) == + (SCL_CONFIG | SCL_STATE) && + dsl_pool_sync_context(spa_get_dsl(zio->io_spa)))); + ASSERT(flags & ZIO_FLAG_CONFIG_WRITER); zio_nowait(zio_write_phys(zio, vd, vdev_label_offset(vd->vdev_psize, l, offset), @@ -317,24 +335,23 @@ vdev_label_read_config(vdev_t *vd) nvlist_t *config = NULL; vdev_phys_t *vp; zio_t *zio; - int l; + int flags = + ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE; - ASSERT(spa_config_held(spa, RW_READER) || - spa_config_held(spa, RW_WRITER)); + ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL); if (!vdev_readable(vd)) return (NULL); vp = zio_buf_alloc(sizeof (vdev_phys_t)); - for (l = 0; l < VDEV_LABELS; l++) { + for (int l = 0; l < VDEV_LABELS; l++) { - zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL | - ZIO_FLAG_SPECULATIVE | ZIO_FLAG_CONFIG_HELD); + zio = zio_root(spa, NULL, NULL, flags); vdev_label_read(zio, vd, l, vp, offsetof(vdev_label_t, vl_vdev_phys), - sizeof (vdev_phys_t), NULL, NULL); + sizeof (vdev_phys_t), NULL, NULL, flags); if (zio_wait(zio) == 0 && nvlist_unpack(vp->vp_nvlist, sizeof (vp->vp_nvlist), @@ -405,7 +422,7 @@ vdev_inuse(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason, */ if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE && !spa_guid_exists(pool_guid, device_guid) && - !spa_spare_exists(device_guid, NULL) && + !spa_spare_exists(device_guid, NULL, NULL) && !spa_l2cache_exists(device_guid, NULL)) return (B_FALSE); @@ -425,7 +442,7 @@ vdev_inuse(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason, * spa_has_spare() here because it may be on our pending list of spares * to add. We also check if it is an l2cache device. */ - if (spa_spare_exists(device_guid, &spare_pool) || + if (spa_spare_exists(device_guid, &spare_pool, NULL) || spa_has_spare(spa, device_guid)) { if (spare_guid) *spare_guid = device_guid; @@ -474,16 +491,15 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) vdev_boot_header_t *vb; uberblock_t *ub; zio_t *zio; - int l, c, n; char *buf; size_t buflen; int error; uint64_t spare_guid, l2cache_guid; - int flags = ZIO_FLAG_CONFIG_HELD | ZIO_FLAG_CANFAIL; + int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; - ASSERT(spa_config_held(spa, RW_WRITER)); + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); - for (c = 0; c < vd->vdev_children; c++) + for (int c = 0; c < vd->vdev_children; c++) if ((error = vdev_label_init(vd->vdev_child[c], crtxg, reason)) != 0) return (error); @@ -515,14 +531,12 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) */ if (reason != VDEV_LABEL_REMOVE && reason != VDEV_LABEL_L2CACHE && spare_guid != 0ULL) { - vdev_t *pvd = vd->vdev_parent; + uint64_t guid_delta = spare_guid - vd->vdev_guid; - for (; pvd != NULL; pvd = pvd->vdev_parent) { - pvd->vdev_guid_sum -= vd->vdev_guid; - pvd->vdev_guid_sum += spare_guid; - } + vd->vdev_guid += guid_delta; - vd->vdev_guid = vd->vdev_guid_sum = spare_guid; + for (vdev_t *pvd = vd; pvd != NULL; pvd = pvd->vdev_parent) + pvd->vdev_guid_sum += guid_delta; /* * If this is a replacement, then we want to fallthrough to the @@ -536,14 +550,12 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) if (reason != VDEV_LABEL_REMOVE && reason != VDEV_LABEL_SPARE && l2cache_guid != 0ULL) { - vdev_t *pvd = vd->vdev_parent; + uint64_t guid_delta = l2cache_guid - vd->vdev_guid; - for (; pvd != NULL; pvd = pvd->vdev_parent) { - pvd->vdev_guid_sum -= vd->vdev_guid; - pvd->vdev_guid_sum += l2cache_guid; - } + vd->vdev_guid += guid_delta; - vd->vdev_guid = vd->vdev_guid_sum = l2cache_guid; + for (vdev_t *pvd = vd; pvd != NULL; pvd = pvd->vdev_parent) + pvd->vdev_guid_sum += guid_delta; /* * If this is a replacement, then we want to fallthrough to the @@ -643,7 +655,7 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) */ zio = zio_root(spa, NULL, NULL, flags); - for (l = 0; l < VDEV_LABELS; l++) { + for (int l = 0; l < VDEV_LABELS; l++) { vdev_label_write(zio, vd, l, vp, offsetof(vdev_label_t, vl_vdev_phys), @@ -653,7 +665,7 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) offsetof(vdev_label_t, vl_boot_header), sizeof (vdev_boot_header_t), NULL, NULL, flags); - for (n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) { + for (int n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) { vdev_label_write(zio, vd, l, ub, VDEV_UBERBLOCK_OFFSET(vd, n), VDEV_UBERBLOCK_SIZE(vd), NULL, NULL, flags); @@ -675,7 +687,7 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) */ if (error == 0 && !vd->vdev_isspare && (reason == VDEV_LABEL_SPARE || - spa_spare_exists(vd->vdev_guid, NULL))) + spa_spare_exists(vd->vdev_guid, NULL, NULL))) spa_spare_add(vd); if (error == 0 && !vd->vdev_isl2cache && @@ -721,17 +733,17 @@ vdev_uberblock_compare(uberblock_t *ub1, uberblock_t *ub2) static void vdev_uberblock_load_done(zio_t *zio) { + zio_t *rio = zio->io_private; uberblock_t *ub = zio->io_data; - uberblock_t *ubbest = zio->io_private; - spa_t *spa = zio->io_spa; + uberblock_t *ubbest = rio->io_private; ASSERT3U(zio->io_size, ==, VDEV_UBERBLOCK_SIZE(zio->io_vd)); if (zio->io_error == 0 && uberblock_verify(ub) == 0) { - mutex_enter(&spa->spa_uberblock_lock); + mutex_enter(&rio->io_lock); if (vdev_uberblock_compare(ub, ubbest) > 0) *ubbest = *ub; - mutex_exit(&spa->spa_uberblock_lock); + mutex_exit(&rio->io_lock); } zio_buf_free(zio->io_data, zio->io_size); @@ -740,26 +752,39 @@ vdev_uberblock_load_done(zio_t *zio) void vdev_uberblock_load(zio_t *zio, vdev_t *vd, uberblock_t *ubbest) { - int l, c, n; + spa_t *spa = vd->vdev_spa; + vdev_t *rvd = spa->spa_root_vdev; + int flags = + ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE; - for (c = 0; c < vd->vdev_children; c++) + if (vd == rvd) { + ASSERT(zio == NULL); + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); + zio = zio_root(spa, NULL, ubbest, flags); + bzero(ubbest, sizeof (uberblock_t)); + } + + ASSERT(zio != NULL); + + for (int c = 0; c < vd->vdev_children; c++) vdev_uberblock_load(zio, vd->vdev_child[c], ubbest); - if (!vd->vdev_ops->vdev_op_leaf) - return; - - if (vdev_is_dead(vd)) - return; - - for (l = 0; l < VDEV_LABELS; l++) { - for (n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) { - vdev_label_read(zio, vd, l, - zio_buf_alloc(VDEV_UBERBLOCK_SIZE(vd)), - VDEV_UBERBLOCK_OFFSET(vd, n), - VDEV_UBERBLOCK_SIZE(vd), - vdev_uberblock_load_done, ubbest); + if (vd->vdev_ops->vdev_op_leaf && vdev_readable(vd)) { + for (int l = 0; l < VDEV_LABELS; l++) { + for (int n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) { + vdev_label_read(zio, vd, l, + zio_buf_alloc(VDEV_UBERBLOCK_SIZE(vd)), + VDEV_UBERBLOCK_OFFSET(vd, n), + VDEV_UBERBLOCK_SIZE(vd), + vdev_uberblock_load_done, zio, flags); + } } } + + if (vd == rvd) { + (void) zio_wait(zio); + spa_config_exit(spa, SCL_ALL, FTAG); + } } /* @@ -779,18 +804,18 @@ vdev_uberblock_sync_done(zio_t *zio) * Write the uberblock to all labels of all leaves of the specified vdev. */ static void -vdev_uberblock_sync(zio_t *zio, uberblock_t *ub, vdev_t *vd) +vdev_uberblock_sync(zio_t *zio, uberblock_t *ub, vdev_t *vd, int flags) { - int l, c, n; uberblock_t *ubbuf; + int n; - for (c = 0; c < vd->vdev_children; c++) - vdev_uberblock_sync(zio, ub, vd->vdev_child[c]); + for (int c = 0; c < vd->vdev_children; c++) + vdev_uberblock_sync(zio, ub, vd->vdev_child[c], flags); if (!vd->vdev_ops->vdev_op_leaf) return; - if (vdev_is_dead(vd)) + if (!vdev_writeable(vd)) return; n = ub->ub_txg & (VDEV_UBERBLOCK_COUNT(vd) - 1); @@ -799,12 +824,11 @@ vdev_uberblock_sync(zio_t *zio, uberblock_t *ub, vdev_t *vd) bzero(ubbuf, VDEV_UBERBLOCK_SIZE(vd)); *ubbuf = *ub; - for (l = 0; l < VDEV_LABELS; l++) + for (int l = 0; l < VDEV_LABELS; l++) vdev_label_write(zio, vd, l, ubbuf, - VDEV_UBERBLOCK_OFFSET(vd, n), - VDEV_UBERBLOCK_SIZE(vd), + VDEV_UBERBLOCK_OFFSET(vd, n), VDEV_UBERBLOCK_SIZE(vd), vdev_uberblock_sync_done, zio->io_private, - ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE); + flags | ZIO_FLAG_DONT_PROPAGATE); zio_buf_free(ubbuf, VDEV_UBERBLOCK_SIZE(vd)); } @@ -813,14 +837,13 @@ int vdev_uberblock_sync_list(vdev_t **svd, int svdcount, uberblock_t *ub, int flags) { spa_t *spa = svd[0]->vdev_spa; - int v; zio_t *zio; uint64_t good_writes = 0; zio = zio_root(spa, NULL, &good_writes, flags); - for (v = 0; v < svdcount; v++) - vdev_uberblock_sync(zio, ub, svd[v]); + for (int v = 0; v < svdcount; v++) + vdev_uberblock_sync(zio, ub, svd[v], flags); (void) zio_wait(zio); @@ -831,7 +854,7 @@ vdev_uberblock_sync_list(vdev_t **svd, int svdcount, uberblock_t *ub, int flags) */ zio = zio_root(spa, NULL, NULL, flags); - for (v = 0; v < svdcount; v++) + for (int v = 0; v < svdcount; v++) zio_flush(zio, svd[v]); (void) zio_wait(zio); @@ -865,25 +888,33 @@ vdev_label_sync_top_done(zio_t *zio) kmem_free(good_writes, sizeof (uint64_t)); } +/* + * We ignore errors for log and cache devices, simply free the private data. + */ +static void +vdev_label_sync_ignore_done(zio_t *zio) +{ + kmem_free(zio->io_private, sizeof (uint64_t)); +} + /* * Write all even or odd labels to all leaves of the specified vdev. */ static void -vdev_label_sync(zio_t *zio, vdev_t *vd, int l, uint64_t txg) +vdev_label_sync(zio_t *zio, vdev_t *vd, int l, uint64_t txg, int flags) { nvlist_t *label; vdev_phys_t *vp; char *buf; size_t buflen; - int c; - for (c = 0; c < vd->vdev_children; c++) - vdev_label_sync(zio, vd->vdev_child[c], l, txg); + for (int c = 0; c < vd->vdev_children; c++) + vdev_label_sync(zio, vd->vdev_child[c], l, txg, flags); if (!vd->vdev_ops->vdev_op_leaf) return; - if (vdev_is_dead(vd)) + if (!vdev_writeable(vd)) return; /* @@ -903,7 +934,7 @@ vdev_label_sync(zio_t *zio, vdev_t *vd, int l, uint64_t txg) offsetof(vdev_label_t, vl_vdev_phys), sizeof (vdev_phys_t), vdev_label_sync_done, zio->io_private, - ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE); + flags | ZIO_FLAG_DONT_PROPAGATE); } } @@ -912,9 +943,9 @@ vdev_label_sync(zio_t *zio, vdev_t *vd, int l, uint64_t txg) } int -vdev_label_sync_list(spa_t *spa, int l, int flags, uint64_t txg) +vdev_label_sync_list(spa_t *spa, int l, uint64_t txg, int flags) { - list_t *dl = &spa->spa_dirty_list; + list_t *dl = &spa->spa_config_dirty_list; vdev_t *vd; zio_t *zio; int error; @@ -927,9 +958,11 @@ vdev_label_sync_list(spa_t *spa, int l, int flags, uint64_t txg) for (vd = list_head(dl); vd != NULL; vd = list_next(dl, vd)) { uint64_t *good_writes = kmem_zalloc(sizeof (uint64_t), KM_SLEEP); - zio_t *vio = zio_null(zio, spa, vdev_label_sync_top_done, + zio_t *vio = zio_null(zio, spa, + (vd->vdev_islog || vd->vdev_aux != NULL) ? + vdev_label_sync_ignore_done : vdev_label_sync_top_done, good_writes, flags); - vdev_label_sync(vio, vd, l, txg); + vdev_label_sync(vio, vd, l, txg, flags); zio_nowait(vio); } @@ -967,7 +1000,7 @@ vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg) vdev_t *vd; zio_t *zio; int error; - int flags = ZIO_FLAG_CONFIG_HELD | ZIO_FLAG_CANFAIL; + int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; ASSERT(ub->ub_txg <= txg); @@ -979,7 +1012,7 @@ vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg) */ if (ub->ub_txg < txg && uberblock_update(ub, spa->spa_root_vdev, txg) == B_FALSE && - list_is_empty(&spa->spa_dirty_list)) + list_is_empty(&spa->spa_config_dirty_list)) return (0); if (txg > spa_freeze_txg(spa)) @@ -1010,7 +1043,7 @@ vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg) * the new labels to disk to ensure that all even-label updates * are committed to stable storage before the uberblock update. */ - if ((error = vdev_label_sync_list(spa, 0, flags, txg)) != 0) + if ((error = vdev_label_sync_list(spa, 0, txg, flags)) != 0) return (error); /* @@ -1041,5 +1074,5 @@ vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg) * to disk to ensure that all odd-label updates are committed to * stable storage before the next transaction group begins. */ - return (vdev_label_sync_list(spa, 1, flags, txg)); + return (vdev_label_sync_list(spa, 1, txg, flags)); } diff --git a/zfs/lib/libzpool/vdev_mirror.c b/zfs/lib/libzpool/vdev_mirror.c index 16063fa9a..c4629ff45 100644 --- a/zfs/lib/libzpool/vdev_mirror.c +++ b/zfs/lib/libzpool/vdev_mirror.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)vdev_mirror.c 1.9 07/11/27 SMI" - #include #include #include @@ -39,8 +37,9 @@ typedef struct mirror_child { vdev_t *mc_vd; uint64_t mc_offset; int mc_error; - short mc_tried; - short mc_skipped; + uint8_t mc_tried; + uint8_t mc_skipped; + uint8_t mc_speculative; } mirror_child_t; typedef struct mirror_map { @@ -53,6 +52,14 @@ typedef struct mirror_map { int vdev_mirror_shift = 21; +static void +vdev_mirror_map_free(zio_t *zio) +{ + mirror_map_t *mm = zio->io_vsd; + + kmem_free(mm, offsetof(mirror_map_t, mm_child[mm->mm_children])); +} + static mirror_map_t * vdev_mirror_map_alloc(zio_t *zio) { @@ -110,18 +117,10 @@ vdev_mirror_map_alloc(zio_t *zio) } zio->io_vsd = mm; + zio->io_vsd_free = vdev_mirror_map_free; return (mm); } -static void -vdev_mirror_map_free(zio_t *zio) -{ - mirror_map_t *mm = zio->io_vsd; - - kmem_free(mm, offsetof(mirror_map_t, mm_child[mm->mm_children])); - zio->io_vsd = NULL; -} - static int vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift) { @@ -195,13 +194,6 @@ vdev_mirror_scrub_done(zio_t *zio) mc->mc_skipped = 0; } -static void -vdev_mirror_repair_done(zio_t *zio) -{ - ASSERT(zio->io_private == zio->io_parent); - vdev_mirror_map_free(zio->io_private); -} - /* * Try to find a child whose DTL doesn't contain the block we want to read. * If we can't, try the read on any vdev we haven't already tried. @@ -227,7 +219,7 @@ vdev_mirror_child_select(zio_t *zio) mc = &mm->mm_child[c]; if (mc->mc_tried || mc->mc_skipped) continue; - if (vdev_is_dead(mc->mc_vd) && !vdev_readable(mc->mc_vd)) { + if (!vdev_readable(mc->mc_vd)) { mc->mc_error = ENXIO; mc->mc_tried = 1; /* don't even try */ mc->mc_skipped = 1; @@ -237,6 +229,7 @@ vdev_mirror_child_select(zio_t *zio) return (c); mc->mc_error = ESTALE; mc->mc_skipped = 1; + mc->mc_speculative = 1; } /* @@ -275,11 +268,10 @@ vdev_mirror_io_start(zio_t *zio) zio_nowait(zio_vdev_child_io(zio, zio->io_bp, mc->mc_vd, mc->mc_offset, zio_buf_alloc(zio->io_size), zio->io_size, - zio->io_type, zio->io_priority, - ZIO_FLAG_CANFAIL, + zio->io_type, zio->io_priority, 0, vdev_mirror_scrub_done, mc)); } - return (zio_wait_for_children_done(zio)); + return (ZIO_PIPELINE_CONTINUE); } /* * For normal reads just pick one child. @@ -309,16 +301,30 @@ vdev_mirror_io_start(zio_t *zio) while (children--) { mc = &mm->mm_child[c]; zio_nowait(zio_vdev_child_io(zio, zio->io_bp, - mc->mc_vd, mc->mc_offset, - zio->io_data, zio->io_size, zio->io_type, zio->io_priority, - ZIO_FLAG_CANFAIL, vdev_mirror_child_done, mc)); + mc->mc_vd, mc->mc_offset, zio->io_data, zio->io_size, + zio->io_type, zio->io_priority, 0, + vdev_mirror_child_done, mc)); c++; } - return (zio_wait_for_children_done(zio)); + return (ZIO_PIPELINE_CONTINUE); } static int +vdev_mirror_worst_error(mirror_map_t *mm) +{ + int error[2] = { 0, 0 }; + + for (int c = 0; c < mm->mm_children; c++) { + mirror_child_t *mc = &mm->mm_child[c]; + int s = mc->mc_speculative; + error[s] = zio_worst_error(error[s], mc->mc_error); + } + + return (error[0] ? error[0] : error[1]); +} + +static void vdev_mirror_io_done(zio_t *zio) { mirror_map_t *mm = zio->io_vsd; @@ -327,41 +333,46 @@ vdev_mirror_io_done(zio_t *zio) int good_copies = 0; int unexpected_errors = 0; - zio->io_error = 0; - zio->io_numerrors = 0; - for (c = 0; c < mm->mm_children; c++) { mc = &mm->mm_child[c]; - if (mc->mc_tried && mc->mc_error == 0) { - good_copies++; - continue; - } - - /* - * We preserve any EIOs because those may be worth retrying; - * whereas ECKSUM and ENXIO are more likely to be persistent. - */ if (mc->mc_error) { - if (zio->io_error != EIO) - zio->io_error = mc->mc_error; if (!mc->mc_skipped) unexpected_errors++; - zio->io_numerrors++; + } else if (mc->mc_tried) { + good_copies++; } } if (zio->io_type == ZIO_TYPE_WRITE) { /* * XXX -- for now, treat partial writes as success. - * XXX -- For a replacing vdev, we need to make sure the - * new child succeeds. + * + * Now that we support write reallocation, it would be better + * to treat partial failure as real failure unless there are + * no non-degraded top-level vdevs left, and not update DTLs + * if we intend to reallocate. */ /* XXPOLICY */ - if (good_copies != 0) - zio->io_error = 0; - vdev_mirror_map_free(zio); - return (ZIO_PIPELINE_CONTINUE); + if (good_copies != mm->mm_children) { + /* + * Always require at least one good copy. + * + * For ditto blocks (io_vd == NULL), require + * all copies to be good. + * + * XXX -- for replacing vdevs, there's no great answer. + * If the old device is really dead, we may not even + * be able to access it -- so we only want to + * require good writes to the new device. But if + * the new device turns out to be flaky, we want + * to be able to detach it -- which requires all + * writes to the old device to have succeeded. + */ + if (good_copies == 0 || zio->io_vd == NULL) + zio->io_error = vdev_mirror_worst_error(mm); + } + return; } ASSERT(zio->io_type == ZIO_TYPE_READ); @@ -373,39 +384,27 @@ vdev_mirror_io_done(zio_t *zio) if (good_copies == 0 && (c = vdev_mirror_child_select(zio)) != -1) { ASSERT(c >= 0 && c < mm->mm_children); mc = &mm->mm_child[c]; - dprintf("retrying i/o (err=%d) on child %s\n", - zio->io_error, vdev_description(mc->mc_vd)); - zio->io_error = 0; zio_vdev_io_redone(zio); zio_nowait(zio_vdev_child_io(zio, zio->io_bp, mc->mc_vd, mc->mc_offset, zio->io_data, zio->io_size, - ZIO_TYPE_READ, zio->io_priority, ZIO_FLAG_CANFAIL, + ZIO_TYPE_READ, zio->io_priority, 0, vdev_mirror_child_done, mc)); - return (zio_wait_for_children_done(zio)); + return; } /* XXPOLICY */ - if (good_copies) - zio->io_error = 0; - else + if (good_copies == 0) { + zio->io_error = vdev_mirror_worst_error(mm); ASSERT(zio->io_error != 0); + } if (good_copies && (spa_mode & FWRITE) && (unexpected_errors || (zio->io_flags & ZIO_FLAG_RESILVER) || ((zio->io_flags & ZIO_FLAG_SCRUB) && mm->mm_replacing))) { - zio_t *rio; - /* * Use the good data we have in hand to repair damaged children. - * - * We issue all repair I/Os as children of 'rio' to arrange - * that vdev_mirror_map_free(zio) will be invoked after all - * repairs complete, but before we advance to the next stage. */ - rio = zio_null(zio, zio->io_spa, - vdev_mirror_repair_done, zio, ZIO_FLAG_CANFAIL); - for (c = 0; c < mm->mm_children; c++) { /* * Don't rewrite known good children. @@ -426,25 +425,13 @@ vdev_mirror_io_done(zio_t *zio) mc->mc_error = ESTALE; } - dprintf("resilvered %s @ 0x%llx error %d\n", - vdev_description(mc->mc_vd), mc->mc_offset, - mc->mc_error); - - zio_nowait(zio_vdev_child_io(rio, zio->io_bp, mc->mc_vd, - mc->mc_offset, zio->io_data, zio->io_size, + zio_nowait(zio_vdev_child_io(zio, zio->io_bp, + mc->mc_vd, mc->mc_offset, + zio->io_data, zio->io_size, ZIO_TYPE_WRITE, zio->io_priority, - ZIO_FLAG_IO_REPAIR | ZIO_FLAG_CANFAIL | - ZIO_FLAG_DONT_PROPAGATE, NULL, NULL)); + ZIO_FLAG_IO_REPAIR, NULL, NULL)); } - - zio_nowait(rio); - - return (zio_wait_for_children_done(zio)); } - - vdev_mirror_map_free(zio); - - return (ZIO_PIPELINE_CONTINUE); } static void @@ -462,7 +449,6 @@ vdev_mirror_state_change(vdev_t *vd, int faulted, int degraded) vdev_ops_t vdev_mirror_ops = { vdev_mirror_open, vdev_mirror_close, - NULL, vdev_default_asize, vdev_mirror_io_start, vdev_mirror_io_done, @@ -474,7 +460,6 @@ vdev_ops_t vdev_mirror_ops = { vdev_ops_t vdev_replacing_ops = { vdev_mirror_open, vdev_mirror_close, - NULL, vdev_default_asize, vdev_mirror_io_start, vdev_mirror_io_done, @@ -486,7 +471,6 @@ vdev_ops_t vdev_replacing_ops = { vdev_ops_t vdev_spare_ops = { vdev_mirror_open, vdev_mirror_close, - NULL, vdev_default_asize, vdev_mirror_io_start, vdev_mirror_io_done, diff --git a/zfs/lib/libzpool/vdev_missing.c b/zfs/lib/libzpool/vdev_missing.c index 2039f7380..731f7d3dc 100644 --- a/zfs/lib/libzpool/vdev_missing.c +++ b/zfs/lib/libzpool/vdev_missing.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)vdev_missing.c 1.3 07/11/27 SMI" - /* * The 'missing' vdev is a special vdev type used only during import. It * signifies a placeholder in the root vdev for some vdev that we know is @@ -70,23 +68,14 @@ vdev_missing_io_start(zio_t *zio) } /* ARGSUSED */ -static int +static void vdev_missing_io_done(zio_t *zio) { - return (ZIO_PIPELINE_CONTINUE); -} - -/* ARGSUSED */ -static int -vdev_missing_probe(vdev_t *vd) -{ - return (0); } vdev_ops_t vdev_missing_ops = { vdev_missing_open, vdev_missing_close, - vdev_missing_probe, vdev_default_asize, vdev_missing_io_start, vdev_missing_io_done, diff --git a/zfs/lib/libzpool/vdev_queue.c b/zfs/lib/libzpool/vdev_queue.c index db79c8dd2..46fca0e3b 100644 --- a/zfs/lib/libzpool/vdev_queue.c +++ b/zfs/lib/libzpool/vdev_queue.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)vdev_queue.c 1.6 07/11/27 SMI" - #include #include #include @@ -191,6 +189,7 @@ vdev_queue_io_to_issue(vdev_queue_t *vq, uint64_t pending_limit) size = fio->io_size; while ((dio = AVL_PREV(tree, fio)) != NULL && IS_ADJACENT(dio, fio) && + !((dio->io_flags | fio->io_flags) & ZIO_FLAG_DONT_AGGREGATE) && size + dio->io_size <= zfs_vdev_aggregation_limit) { dio->io_delegate_next = fio; fio = dio; @@ -198,6 +197,7 @@ vdev_queue_io_to_issue(vdev_queue_t *vq, uint64_t pending_limit) } while ((dio = AVL_NEXT(tree, lio)) != NULL && IS_ADJACENT(lio, dio) && + !((lio->io_flags | dio->io_flags) & ZIO_FLAG_DONT_AGGREGATE) && size + dio->io_size <= zfs_vdev_aggregation_limit) { lio->io_delegate_next = dio; lio = dio; @@ -207,15 +207,12 @@ vdev_queue_io_to_issue(vdev_queue_t *vq, uint64_t pending_limit) if (fio != lio) { char *buf = zio_buf_alloc(size); uint64_t offset = 0; - int nagg = 0; ASSERT(size <= zfs_vdev_aggregation_limit); - aio = zio_vdev_child_io(fio, NULL, fio->io_vd, - fio->io_offset, buf, size, fio->io_type, - ZIO_PRIORITY_NOW, ZIO_FLAG_DONT_QUEUE | - ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_PROPAGATE | - ZIO_FLAG_NOBOOKMARK, + aio = zio_vdev_delegated_io(fio->io_vd, fio->io_offset, + buf, size, fio->io_type, ZIO_PRIORITY_NOW, + ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE, vdev_queue_agg_io_done, NULL); aio->io_delegate_list = fio; @@ -228,16 +225,10 @@ vdev_queue_io_to_issue(vdev_queue_t *vq, uint64_t pending_limit) offset += dio->io_size; vdev_queue_io_remove(vq, dio); zio_vdev_io_bypass(dio); - nagg++; } ASSERT(offset == size); - dprintf("%5s T=%llu off=%8llx agg=%3d " - "old=%5llx new=%5llx\n", - zio_type_name[fio->io_type], - fio->io_deadline, fio->io_offset, nagg, fio->io_size, size); - avl_add(&vq->vq_pending_tree, aio); return (aio); @@ -271,8 +262,7 @@ vdev_queue_io(zio_t *zio) mutex_enter(&vq->vq_lock); - zio->io_deadline = (zio->io_timestamp >> zfs_vdev_time_shift) + - zio->io_priority; + zio->io_deadline = (lbolt64 >> zfs_vdev_time_shift) + zio->io_priority; vdev_queue_io_add(vq, zio); @@ -295,15 +285,13 @@ void vdev_queue_io_done(zio_t *zio) { vdev_queue_t *vq = &zio->io_vd->vdev_queue; - zio_t *nio; - int i; mutex_enter(&vq->vq_lock); avl_remove(&vq->vq_pending_tree, zio); - for (i = 0; i < zfs_vdev_ramp_rate; i++) { - nio = vdev_queue_io_to_issue(vq, zfs_vdev_max_pending); + for (int i = 0; i < zfs_vdev_ramp_rate; i++) { + zio_t *nio = vdev_queue_io_to_issue(vq, zfs_vdev_max_pending); if (nio == NULL) break; mutex_exit(&vq->vq_lock); diff --git a/zfs/lib/libzpool/vdev_raidz.c b/zfs/lib/libzpool/vdev_raidz.c index cb399f046..69e314468 100644 --- a/zfs/lib/libzpool/vdev_raidz.c +++ b/zfs/lib/libzpool/vdev_raidz.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)vdev_raidz.c 1.10 07/11/27 SMI" - #include #include #include @@ -194,6 +192,18 @@ vdev_raidz_exp2(uint_t a, int exp) return (vdev_raidz_pow2[exp]); } +static void +vdev_raidz_map_free(zio_t *zio) +{ + raidz_map_t *rm = zio->io_vsd; + int c; + + for (c = 0; c < rm->rm_firstdatacol; c++) + zio_buf_free(rm->rm_col[c].rc_data, rm->rm_col[c].rc_size); + + kmem_free(rm, offsetof(raidz_map_t, rm_col[rm->rm_cols])); +} + static raidz_map_t * vdev_raidz_map_alloc(zio_t *zio, uint64_t unit_shift, uint64_t dcols, uint64_t nparity) @@ -276,22 +286,10 @@ vdev_raidz_map_alloc(zio_t *zio, uint64_t unit_shift, uint64_t dcols, } zio->io_vsd = rm; + zio->io_vsd_free = vdev_raidz_map_free; return (rm); } -static void -vdev_raidz_map_free(zio_t *zio) -{ - raidz_map_t *rm = zio->io_vsd; - int c; - - for (c = 0; c < rm->rm_firstdatacol; c++) - zio_buf_free(rm->rm_col[c].rc_data, rm->rm_col[c].rc_size); - - kmem_free(rm, offsetof(raidz_map_t, rm_col[rm->rm_cols])); - zio->io_vsd = NULL; -} - static void vdev_raidz_generate_parity_p(raidz_map_t *rm) { @@ -632,13 +630,6 @@ vdev_raidz_child_done(zio_t *zio) rc->rc_skipped = 0; } -static void -vdev_raidz_repair_done(zio_t *zio) -{ - ASSERT(zio->io_private == zio->io_parent); - vdev_raidz_map_free(zio->io_private); -} - static int vdev_raidz_io_start(zio_t *zio) { @@ -669,11 +660,11 @@ vdev_raidz_io_start(zio_t *zio) cvd = vd->vdev_child[rc->rc_devidx]; zio_nowait(zio_vdev_child_io(zio, NULL, cvd, rc->rc_offset, rc->rc_data, rc->rc_size, - zio->io_type, zio->io_priority, ZIO_FLAG_CANFAIL, + zio->io_type, zio->io_priority, 0, vdev_raidz_child_done, rc)); } - return (zio_wait_for_children_done(zio)); + return (ZIO_PIPELINE_CONTINUE); } ASSERT(zio->io_type == ZIO_TYPE_READ); @@ -709,12 +700,12 @@ vdev_raidz_io_start(zio_t *zio) (zio->io_flags & ZIO_FLAG_SCRUB)) { zio_nowait(zio_vdev_child_io(zio, NULL, cvd, rc->rc_offset, rc->rc_data, rc->rc_size, - zio->io_type, zio->io_priority, ZIO_FLAG_CANFAIL, + zio->io_type, zio->io_priority, 0, vdev_raidz_child_done, rc)); } } - return (zio_wait_for_children_done(zio)); + return (ZIO_PIPELINE_CONTINUE); } /* @@ -724,8 +715,6 @@ static void raidz_checksum_error(zio_t *zio, raidz_col_t *rc) { vdev_t *vd = zio->io_vd->vdev_child[rc->rc_devidx]; - dprintf_bp(zio->io_bp, "imputed checksum error on %s: ", - vdev_description(vd)); if (!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { mutex_enter(&vd->vdev_stat_lock); @@ -784,6 +773,17 @@ static uint64_t raidz_corrected_q; static uint64_t raidz_corrected_pq; static int +vdev_raidz_worst_error(raidz_map_t *rm) +{ + int error = 0; + + for (int c = 0; c < rm->rm_cols; c++) + error = zio_worst_error(error, rm->rm_col[c].rc_error); + + return (error); +} + +static void vdev_raidz_io_done(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -794,26 +794,19 @@ vdev_raidz_io_done(zio_t *zio) int parity_errors = 0; int parity_untried = 0; int data_errors = 0; + int total_errors = 0; int n, c, c1; ASSERT(zio->io_bp != NULL); /* XXX need to add code to enforce this */ - zio->io_error = 0; - zio->io_numerrors = 0; - ASSERT(rm->rm_missingparity <= rm->rm_firstdatacol); ASSERT(rm->rm_missingdata <= rm->rm_cols - rm->rm_firstdatacol); for (c = 0; c < rm->rm_cols; c++) { rc = &rm->rm_col[c]; - /* - * We preserve any EIOs because those may be worth retrying; - * whereas ECKSUM and ENXIO are more likely to be persistent. - */ if (rc->rc_error) { - if (zio->io_error != EIO) - zio->io_error = rc->rc_error; + ASSERT(rc->rc_error != ECKSUM); /* child has no bp */ if (c < rm->rm_firstdatacol) parity_errors++; @@ -823,7 +816,7 @@ vdev_raidz_io_done(zio_t *zio) if (!rc->rc_skipped) unexpected_errors++; - zio->io_numerrors++; + total_errors++; } else if (c < rm->rm_firstdatacol && !rc->rc_tried) { parity_untried++; } @@ -831,17 +824,20 @@ vdev_raidz_io_done(zio_t *zio) if (zio->io_type == ZIO_TYPE_WRITE) { /* - * If this is not a failfast write, and we were able to - * write enough columns to reconstruct the data, good enough. + * XXX -- for now, treat partial writes as a success. + * (If we couldn't write enough columns to reconstruct + * the data, the I/O failed. Otherwise, good enough.) + * + * Now that we support write reallocation, it would be better + * to treat partial failure as real failure unless there are + * no non-degraded top-level vdevs left, and not update DTLs + * if we intend to reallocate. */ /* XXPOLICY */ - if (zio->io_numerrors <= rm->rm_firstdatacol && - !(zio->io_flags & ZIO_FLAG_FAILFAST)) - zio->io_error = 0; + if (total_errors > rm->rm_firstdatacol) + zio->io_error = vdev_raidz_worst_error(rm); - vdev_raidz_map_free(zio); - - return (ZIO_PIPELINE_CONTINUE); + return; } ASSERT(zio->io_type == ZIO_TYPE_READ); @@ -862,12 +858,10 @@ vdev_raidz_io_done(zio_t *zio) * has a valid checksum. Naturally, this case applies in the absence of * any errors. */ - if (zio->io_numerrors <= rm->rm_firstdatacol - parity_untried) { + if (total_errors <= rm->rm_firstdatacol - parity_untried) { switch (data_errors) { case 0: if (zio_checksum_error(zio) == 0) { - zio->io_error = 0; - /* * If we read parity information (unnecessarily * as it happens since no reconstruction was @@ -919,7 +913,6 @@ vdev_raidz_io_done(zio_t *zio) } if (zio_checksum_error(zio) == 0) { - zio->io_error = 0; if (rm->rm_col[VDEV_RAIDZ_P].rc_error == 0) atomic_inc_64(&raidz_corrected_p); else @@ -981,9 +974,7 @@ vdev_raidz_io_done(zio_t *zio) vdev_raidz_reconstruct_pq(rm, c1, c); if (zio_checksum_error(zio) == 0) { - zio->io_error = 0; atomic_inc_64(&raidz_corrected_pq); - goto done; } break; @@ -1009,7 +1000,6 @@ vdev_raidz_io_done(zio_t *zio) if (rm->rm_col[c].rc_tried) continue; - zio->io_error = 0; zio_vdev_io_redone(zio); do { rc = &rm->rm_col[c]; @@ -1018,12 +1008,11 @@ vdev_raidz_io_done(zio_t *zio) zio_nowait(zio_vdev_child_io(zio, NULL, vd->vdev_child[rc->rc_devidx], rc->rc_offset, rc->rc_data, rc->rc_size, - zio->io_type, zio->io_priority, ZIO_FLAG_CANFAIL, + zio->io_type, zio->io_priority, 0, vdev_raidz_child_done, rc)); } while (++c < rm->rm_cols); - dprintf("rereading\n"); - return (zio_wait_for_children_done(zio)); + return; } /* @@ -1034,8 +1023,15 @@ vdev_raidz_io_done(zio_t *zio) * in absent data. Before we attempt combinatorial reconstruction make * sure we have a chance of coming up with the right answer. */ - if (zio->io_numerrors >= rm->rm_firstdatacol) { - ASSERT(zio->io_error != 0); + if (total_errors >= rm->rm_firstdatacol) { + zio->io_error = vdev_raidz_worst_error(rm); + /* + * If there were exactly as many device errors as parity + * columns, yet we couldn't reconstruct the data, then at + * least one device must have returned bad data silently. + */ + if (total_errors == rm->rm_firstdatacol) + zio->io_error = zio_worst_error(zio->io_error, ECKSUM); goto done; } @@ -1053,7 +1049,6 @@ vdev_raidz_io_done(zio_t *zio) if (zio_checksum_error(zio) == 0) { zio_buf_free(orig, rc->rc_size); - zio->io_error = 0; atomic_inc_64(&raidz_corrected_p); /* @@ -1085,7 +1080,6 @@ vdev_raidz_io_done(zio_t *zio) if (zio_checksum_error(zio) == 0) { zio_buf_free(orig, rc->rc_size); - zio->io_error = 0; atomic_inc_64(&raidz_corrected_q); /* @@ -1127,7 +1121,6 @@ vdev_raidz_io_done(zio_t *zio) if (zio_checksum_error(zio) == 0) { zio_buf_free(orig, rc->rc_size); zio_buf_free(orig1, rc1->rc_size); - zio->io_error = 0; atomic_inc_64(&raidz_corrected_pq); /* @@ -1159,6 +1152,7 @@ vdev_raidz_io_done(zio_t *zio) * all children. */ zio->io_error = ECKSUM; + if (!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { for (c = 0; c < rm->rm_cols; c++) { rc = &rm->rm_col[c]; @@ -1173,18 +1167,9 @@ done: if (zio->io_error == 0 && (spa_mode & FWRITE) && (unexpected_errors || (zio->io_flags & ZIO_FLAG_RESILVER))) { - zio_t *rio; - /* * Use the good data we have in hand to repair damaged children. - * - * We issue all repair I/Os as children of 'rio' to arrange - * that vdev_raidz_map_free(zio) will be invoked after all - * repairs complete, but before we advance to the next stage. */ - rio = zio_null(zio, zio->io_spa, - vdev_raidz_repair_done, zio, ZIO_FLAG_CANFAIL); - for (c = 0; c < rm->rm_cols; c++) { rc = &rm->rm_col[c]; cvd = vd->vdev_child[rc->rc_devidx]; @@ -1192,26 +1177,12 @@ done: if (rc->rc_error == 0) continue; - dprintf("%s resilvered %s @ 0x%llx error %d\n", - vdev_description(vd), - vdev_description(cvd), - zio->io_offset, rc->rc_error); - - zio_nowait(zio_vdev_child_io(rio, NULL, cvd, + zio_nowait(zio_vdev_child_io(zio, NULL, cvd, rc->rc_offset, rc->rc_data, rc->rc_size, ZIO_TYPE_WRITE, zio->io_priority, - ZIO_FLAG_IO_REPAIR | ZIO_FLAG_DONT_PROPAGATE | - ZIO_FLAG_CANFAIL, NULL, NULL)); + ZIO_FLAG_IO_REPAIR, NULL, NULL)); } - - zio_nowait(rio); - - return (zio_wait_for_children_done(zio)); } - - vdev_raidz_map_free(zio); - - return (ZIO_PIPELINE_CONTINUE); } static void @@ -1229,7 +1200,6 @@ vdev_raidz_state_change(vdev_t *vd, int faulted, int degraded) vdev_ops_t vdev_raidz_ops = { vdev_raidz_open, vdev_raidz_close, - NULL, vdev_raidz_asize, vdev_raidz_io_start, vdev_raidz_io_done, diff --git a/zfs/lib/libzpool/vdev_root.c b/zfs/lib/libzpool/vdev_root.c index 3bb1fd209..88383f002 100644 --- a/zfs/lib/libzpool/vdev_root.c +++ b/zfs/lib/libzpool/vdev_root.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)vdev_root.c 1.5 07/10/24 SMI" - #include #include #include @@ -48,7 +46,7 @@ static int too_many_errors(vdev_t *vd, int numerrors) { ASSERT3U(numerrors, <=, vd->vdev_children); - return (numerrors == vd->vdev_children); + return (numerrors > 0); } static int @@ -67,22 +65,17 @@ vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift) vdev_t *cvd = vd->vdev_child[c]; int error; - if ((error = vdev_open(cvd)) != 0) { + if ((error = vdev_open(cvd)) != 0 && + !cvd->vdev_islog) { lasterror = error; numerrors++; continue; } } - if (numerrors > 0) { - if (!too_many_errors(vd, numerrors)) { - /* XXX - should not be explicitly setting this state */ - vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED, - VDEV_AUX_NO_REPLICAS); - } else { - vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS; - return (lasterror); - } + if (too_many_errors(vd, numerrors)) { + vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS; + return (lasterror); } *asize = 0; @@ -103,13 +96,9 @@ vdev_root_close(vdev_t *vd) static void vdev_root_state_change(vdev_t *vd, int faulted, int degraded) { - if (faulted) { - if (too_many_errors(vd, faulted)) - vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN, - VDEV_AUX_NO_REPLICAS); - else - vdev_set_state(vd, B_FALSE, VDEV_STATE_FAULTED, - VDEV_AUX_NO_REPLICAS); + if (too_many_errors(vd, faulted)) { + vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN, + VDEV_AUX_NO_REPLICAS); } else if (degraded) { vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE); } else { @@ -120,7 +109,6 @@ vdev_root_state_change(vdev_t *vd, int faulted, int degraded) vdev_ops_t vdev_root_ops = { vdev_root_open, vdev_root_close, - NULL, vdev_default_asize, NULL, /* io_start - not applicable to the root */ NULL, /* io_done - not applicable to the root */ diff --git a/zfs/lib/libzpool/zap.c b/zfs/lib/libzpool/zap.c index f4f456ce8..ca859ec35 100644 --- a/zfs/lib/libzpool/zap.c +++ b/zfs/lib/libzpool/zap.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zap.c 1.13 07/11/19 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* @@ -903,6 +903,10 @@ fzap_remove(zap_name_t *zn, dmu_tx_t *tx) return (err); } +/* + * Helper functions for consumers. + */ + int zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask, char *name) @@ -928,6 +932,53 @@ zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask, return (err); } +int +zap_join(objset_t *os, uint64_t fromobj, uint64_t intoobj, dmu_tx_t *tx) +{ + zap_cursor_t zc; + zap_attribute_t za; + int err; + + for (zap_cursor_init(&zc, os, fromobj); + zap_cursor_retrieve(&zc, &za) == 0; + (void) zap_cursor_advance(&zc)) { + if (za.za_integer_length != 8 || za.za_num_integers != 1) + return (EINVAL); + err = zap_add(os, intoobj, za.za_name, + 8, 1, &za.za_first_integer, tx); + if (err) + return (err); + } + zap_cursor_fini(&zc); + return (0); +} + +int +zap_add_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx) +{ + char name[20]; + + (void) snprintf(name, sizeof (name), "%llx", (longlong_t)value); + return (zap_add(os, obj, name, 8, 1, &value, tx)); +} + +int +zap_remove_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx) +{ + char name[20]; + + (void) snprintf(name, sizeof (name), "%llx", (longlong_t)value); + return (zap_remove(os, obj, name, tx)); +} + +int +zap_lookup_int(objset_t *os, uint64_t obj, uint64_t value) +{ + char name[20]; + + (void) snprintf(name, sizeof (name), "%llx", (longlong_t)value); + return (zap_lookup(os, obj, name, 8, 1, &value)); +} /* * Routines for iterating over the attributes. diff --git a/zfs/lib/libzpool/zap_leaf.c b/zfs/lib/libzpool/zap_leaf.c index 132b7af62..da498b6bc 100644 --- a/zfs/lib/libzpool/zap_leaf.c +++ b/zfs/lib/libzpool/zap_leaf.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zap_leaf.c 1.9 07/11/16 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * The 512-byte leaf is broken into 32 16-byte chunks. diff --git a/zfs/lib/libzpool/zap_micro.c b/zfs/lib/libzpool/zap_micro.c index 7aea76b31..abba42775 100644 --- a/zfs/lib/libzpool/zap_micro.c +++ b/zfs/lib/libzpool/zap_micro.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zap_micro.c 1.12 08/04/27 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libdmu-ctl/zfs_acl.c b/zfs/lib/libzpool/zfs_acl.c similarity index 91% rename from zfs/lib/libdmu-ctl/zfs_acl.c rename to zfs/lib/libzpool/zfs_acl.c index cc2f97e1b..341dc4dfe 100644 --- a/zfs/lib/libdmu-ctl/zfs_acl.c +++ b/zfs/lib/libzpool/zfs_acl.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_acl.c 1.25 08/04/08 SMI" - #include #include #include @@ -58,6 +56,7 @@ #define ALLOW ACE_ACCESS_ALLOWED_ACE_TYPE #define DENY ACE_ACCESS_DENIED_ACE_TYPE #define MAX_ACE_TYPE ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE +#define MIN_ACE_TYPE ALLOW #define OWNING_GROUP (ACE_GROUP|ACE_IDENTIFIER_GROUP) #define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \ @@ -74,7 +73,7 @@ ACE_WRITE_ACL|ACE_DELETE|ACE_DELETE_CHILD|ACE_SYNCHRONIZE) #define WRITE_MASK (WRITE_MASK_DATA|ACE_WRITE_ATTRIBUTES|ACE_WRITE_ACL|\ - ACE_WRITE_OWNER) + ACE_WRITE_OWNER|ACE_DELETE|ACE_DELETE_CHILD) #define OGE_CLEAR (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) @@ -263,7 +262,7 @@ zfs_ace_fuid_size(void *acep) entry_type = (((zfs_ace_hdr_t *)acep)->z_flags & ACE_TYPE_FLAGS); if (entry_type == ACE_OWNER || - entry_type == (ACE_GROUP | ACE_IDENTIFIER_GROUP) || + entry_type == OWNING_GROUP || entry_type == ACE_EVERYONE) return (sizeof (zfs_ace_hdr_t)); /*FALLTHROUGH*/ @@ -395,6 +394,28 @@ zfs_acl_free(zfs_acl_t *aclp) kmem_free(aclp, sizeof (zfs_acl_t)); } +static boolean_t +zfs_acl_valid_ace_type(uint_t type, uint_t flags) +{ + uint16_t entry_type; + + switch (type) { + case ALLOW: + case DENY: + case ACE_SYSTEM_AUDIT_ACE_TYPE: + case ACE_SYSTEM_ALARM_ACE_TYPE: + entry_type = flags & ACE_TYPE_FLAGS; + return (entry_type == ACE_OWNER || + entry_type == OWNING_GROUP || + entry_type == ACE_EVERYONE || entry_type == 0 || + entry_type == ACE_IDENTIFIER_GROUP); + default: + if (type >= MIN_ACE_TYPE && type <= MAX_ACE_TYPE) + return (B_TRUE); + } + return (B_FALSE); +} + static boolean_t zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) { @@ -402,26 +423,9 @@ zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) * first check type of entry */ - switch (iflags & ACE_TYPE_FLAGS) { - case ACE_OWNER: - case (ACE_IDENTIFIER_GROUP | ACE_GROUP): - case ACE_IDENTIFIER_GROUP: - case ACE_EVERYONE: - case 0: /* User entry */ - break; - default: + if (!zfs_acl_valid_ace_type(type, iflags)) return (B_FALSE); - } - - /* - * next check inheritance level flags - */ - - if (type != ALLOW && type > MAX_ACE_TYPE) { - return (B_FALSE); - } - switch (type) { case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: @@ -433,15 +437,11 @@ zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) } /* - * Only directories should have inheritance flags. + * next check inheritance level flags */ - if (obj_type != VDIR && (iflags & - (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE| - ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE))) { - return (B_FALSE); - } - if (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)) + if (obj_type == VDIR && + (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE))) aclp->z_hints |= ZFS_INHERIT_ACE; if (iflags & (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) { @@ -488,12 +488,23 @@ zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who, if (aclnode->z_ace_idx < aclnode->z_ace_count) { void *acep = aclp->z_next_ace; + size_t ace_size; + + /* + * Make sure we don't overstep our bounds + */ + ace_size = aclp->z_ops.ace_size(acep); + + if (((caddr_t)acep + ace_size) > + ((caddr_t)aclnode->z_acldata + aclnode->z_size)) { + return (NULL); + } + *iflags = aclp->z_ops.ace_flags_get(acep); *type = aclp->z_ops.ace_type_get(acep); *access_mask = aclp->z_ops.ace_mask_get(acep); *who = aclp->z_ops.ace_who_get(acep); - aclp->z_next_ace = (caddr_t)aclp->z_next_ace + - aclp->z_ops.ace_size(acep); + aclp->z_next_ace = (caddr_t)aclp->z_next_ace + ace_size; aclnode->z_ace_idx++; return ((void *)acep); } @@ -629,7 +640,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr, entry_type = (iflags & ACE_TYPE_FLAGS); if ((entry_type != ACE_OWNER && - entry_type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) && + entry_type != OWNING_GROUP && entry_type != ACE_EVERYONE)) { acep->a_who = zfs_fuid_map_id(zfsvfs, who, cr, (entry_type & ACE_IDENTIFIER_GROUP) ? @@ -749,7 +760,7 @@ zfs_set_ace(zfs_acl_t *aclp, void *acep, uint32_t access_mask, aclp->z_ops.ace_mask_set(acep, access_mask); aclp->z_ops.ace_type_set(acep, access_type); aclp->z_ops.ace_flags_set(acep, entry_type); - if ((type != ACE_OWNER && type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) && + if ((type != ACE_OWNER && type != OWNING_GROUP && type != ACE_EVERYONE)) aclp->z_ops.ace_who_set(acep, fuid); } @@ -775,14 +786,19 @@ zfs_mode_fuid_compute(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, while (acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, &iflags, &type)) { - /* - * Skip over inherit only ACEs - */ - if (iflags & ACE_INHERIT_ONLY_ACE) + if (!zfs_acl_valid_ace_type(type, iflags)) continue; entry_type = (iflags & ACE_TYPE_FLAGS); + /* + * Skip over owner@, group@ or everyone@ inherit only ACEs + */ + if ((iflags & ACE_INHERIT_ONLY_ACE) && + (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE || + entry_type == OWNING_GROUP)) + continue; + if (entry_type == ACE_OWNER) { if ((access_mask & ACE_READ_DATA) && (!(seen & S_IRUSR))) { @@ -980,6 +996,9 @@ zfs_acl_node_read(znode_t *zp, zfs_acl_t **aclpp, boolean_t will_modify) if (error != 0) { zfs_acl_free(aclp); + /* convert checksum errors into IO errors */ + if (error == ECKSUM) + error = EIO; return (error); } @@ -1647,7 +1666,8 @@ zfs_ace_can_use(znode_t *zp, uint16_t acep_flags) * inherit inheritable ACEs from parent */ static zfs_acl_t * -zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, boolean_t *need_chmod) +zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, uint64_t mode, + boolean_t *need_chmod) { zfsvfs_t *zfsvfs = zp->z_zfsvfs; void *pacep; @@ -1660,106 +1680,123 @@ zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, boolean_t *need_chmod) size_t ace_size; void *data1, *data2; size_t data1sz, data2sz; - enum vtype vntype = ZTOV(zp)->v_type; + boolean_t vdir = ZTOV(zp)->v_type == VDIR; + boolean_t vreg = ZTOV(zp)->v_type == VREG; + boolean_t passthrough, passthrough_x, noallow; + + passthrough_x = + zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X; + passthrough = passthrough_x || + zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH; + noallow = + zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW; *need_chmod = B_TRUE; pacep = NULL; - aclp = zfs_acl_alloc(zfs_acl_version_zp(zp)); - if (zfsvfs->z_acl_inherit != ZFS_ACL_DISCARD) { - while (pacep = zfs_acl_next_ace(paclp, pacep, &who, - &access_mask, &iflags, &type)) { + aclp = zfs_acl_alloc(paclp->z_version); + if (zfsvfs->z_acl_inherit == ZFS_ACL_DISCARD) + return (aclp); + while (pacep = zfs_acl_next_ace(paclp, pacep, &who, + &access_mask, &iflags, &type)) { - if (zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW && - type == ALLOW) - continue; + /* + * don't inherit bogus ACEs + */ + if (!zfs_acl_valid_ace_type(type, iflags)) + continue; - ace_size = aclp->z_ops.ace_size(pacep); + if (noallow && type == ALLOW) + continue; - if (!zfs_ace_can_use(zp, iflags)) - continue; + ace_size = aclp->z_ops.ace_size(pacep); - /* - * If owner@, group@, or everyone@ inheritable - * then zfs_acl_chmod() isn't needed. - */ - if (zfsvfs->z_acl_inherit == - ZFS_ACL_PASSTHROUGH && - ((iflags & (ACE_OWNER|ACE_EVERYONE)) || - ((iflags & OWNING_GROUP) == - OWNING_GROUP)) && (vntype == VREG || - (vntype == VDIR && - (iflags & ACE_DIRECTORY_INHERIT_ACE)))) - *need_chmod = B_FALSE; + if (!zfs_ace_can_use(zp, iflags)) + continue; - aclnode = zfs_acl_node_alloc(ace_size); - list_insert_tail(&aclp->z_acl, aclnode); - acep = aclnode->z_acldata; - zfs_set_ace(aclp, acep, access_mask, type, - who, iflags|ACE_INHERITED_ACE); + /* + * If owner@, group@, or everyone@ inheritable + * then zfs_acl_chmod() isn't needed. + */ + if (passthrough && + ((iflags & (ACE_OWNER|ACE_EVERYONE)) || + ((iflags & OWNING_GROUP) == + OWNING_GROUP)) && (vreg || (vdir && (iflags & + ACE_DIRECTORY_INHERIT_ACE)))) { + *need_chmod = B_FALSE; + + if (!vdir && passthrough_x && + ((mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)) { + access_mask &= ~ACE_EXECUTE; + } + } + + aclnode = zfs_acl_node_alloc(ace_size); + list_insert_tail(&aclp->z_acl, aclnode); + acep = aclnode->z_acldata; + + zfs_set_ace(aclp, acep, access_mask, type, + who, iflags|ACE_INHERITED_ACE); + + /* + * Copy special opaque data if any + */ + if ((data1sz = paclp->z_ops.ace_data(pacep, &data1)) != 0) { + VERIFY((data2sz = aclp->z_ops.ace_data(acep, + &data2)) == data1sz); + bcopy(data1, data2, data2sz); + } + aclp->z_acl_count++; + aclnode->z_ace_count++; + aclp->z_acl_bytes += aclnode->z_size; + newflags = aclp->z_ops.ace_flags_get(acep); + + if (vdir) + aclp->z_hints |= ZFS_INHERIT_ACE; + + if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) || !vdir) { + newflags &= ~ALL_INHERIT; + aclp->z_ops.ace_flags_set(acep, + newflags|ACE_INHERITED_ACE); + zfs_restricted_update(zfsvfs, aclp, acep); + continue; + } + + ASSERT(vdir); + + newflags = aclp->z_ops.ace_flags_get(acep); + if ((iflags & (ACE_FILE_INHERIT_ACE | + ACE_DIRECTORY_INHERIT_ACE)) != + ACE_FILE_INHERIT_ACE) { + aclnode2 = zfs_acl_node_alloc(ace_size); + list_insert_tail(&aclp->z_acl, aclnode2); + acep2 = aclnode2->z_acldata; + zfs_set_ace(aclp, acep2, + access_mask, type, who, + iflags|ACE_INHERITED_ACE); + newflags |= ACE_INHERIT_ONLY_ACE; + aclp->z_ops.ace_flags_set(acep, newflags); + newflags &= ~ALL_INHERIT; + aclp->z_ops.ace_flags_set(acep2, + newflags|ACE_INHERITED_ACE); /* * Copy special opaque data if any */ - if ((data1sz = paclp->z_ops.ace_data(pacep, + if ((data1sz = aclp->z_ops.ace_data(acep, &data1)) != 0) { - VERIFY((data2sz = aclp->z_ops.ace_data(acep, + VERIFY((data2sz = + aclp->z_ops.ace_data(acep2, &data2)) == data1sz); - bcopy(data1, data2, data2sz); + bcopy(data1, data2, data1sz); } aclp->z_acl_count++; - aclnode->z_ace_count++; + aclnode2->z_ace_count++; aclp->z_acl_bytes += aclnode->z_size; - newflags = aclp->z_ops.ace_flags_get(acep); - - if (vntype == VDIR) - aclp->z_hints |= ZFS_INHERIT_ACE; - - if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) || - (vntype != VDIR)) { - newflags &= ~ALL_INHERIT; - aclp->z_ops.ace_flags_set(acep, - newflags|ACE_INHERITED_ACE); - zfs_restricted_update(zfsvfs, aclp, acep); - continue; - } - - ASSERT(vntype == VDIR); - - newflags = aclp->z_ops.ace_flags_get(acep); - if ((iflags & (ACE_FILE_INHERIT_ACE | - ACE_DIRECTORY_INHERIT_ACE)) != - ACE_FILE_INHERIT_ACE) { - aclnode2 = zfs_acl_node_alloc(ace_size); - list_insert_tail(&aclp->z_acl, aclnode2); - acep2 = aclnode2->z_acldata; - zfs_set_ace(aclp, acep2, - access_mask, type, who, - iflags|ACE_INHERITED_ACE); - newflags |= ACE_INHERIT_ONLY_ACE; - aclp->z_ops.ace_flags_set(acep, newflags); - newflags &= ~ALL_INHERIT; - aclp->z_ops.ace_flags_set(acep2, - newflags|ACE_INHERITED_ACE); - - /* - * Copy special opaque data if any - */ - if ((data1sz = aclp->z_ops.ace_data(acep, - &data1)) != 0) { - VERIFY((data2sz = - aclp->z_ops.ace_data(acep2, - &data2)) == data1sz); - bcopy(data1, data2, data1sz); - } - aclp->z_acl_count++; - aclnode2->z_ace_count++; - aclp->z_acl_bytes += aclnode->z_size; - zfs_restricted_update(zfsvfs, aclp, acep2); - } else { - newflags |= ACE_INHERIT_ONLY_ACE; - aclp->z_ops.ace_flags_set(acep, - newflags|ACE_INHERITED_ACE); - } + zfs_restricted_update(zfsvfs, aclp, acep2); + } else { + newflags |= ACE_INHERIT_ONLY_ACE; + aclp->z_ops.ace_flags_set(acep, + newflags|ACE_INHERITED_ACE); } } return (aclp); @@ -1844,11 +1881,13 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag, if (aclp == NULL) { mutex_enter(&parent->z_lock); - if (parent->z_phys->zp_flags & ZFS_INHERIT_ACE) { + if ((ZTOV(parent)->v_type == VDIR && + (parent->z_phys->zp_flags & ZFS_INHERIT_ACE)) && + !(zp->z_phys->zp_flags & ZFS_XATTR)) { mutex_enter(&parent->z_acl_lock); VERIFY(0 == zfs_acl_node_read(parent, &paclp, B_FALSE)); mutex_exit(&parent->z_acl_lock); - aclp = zfs_acl_inherit(zp, paclp, &need_chmod); + aclp = zfs_acl_inherit(zp, paclp, mode, &need_chmod); zfs_acl_free(paclp); } else { aclp = zfs_acl_alloc(zfs_acl_version_zp(zp)); @@ -2230,7 +2269,10 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, while (acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, &iflags, &type)) { - if (iflags & ACE_INHERIT_ONLY_ACE) + if (!zfs_acl_valid_ace_type(type, iflags)) + continue; + + if (ZTOV(zp)->v_type == VDIR && (iflags & ACE_INHERIT_ONLY_ACE)) continue; entry_type = (iflags & ACE_TYPE_FLAGS); @@ -2290,10 +2332,12 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, zfs_acl_free(aclp); /* Put the found 'denies' back on the working mode */ - *working_mode |= deny_mask; - - if (*working_mode) + if (deny_mask) { + *working_mode |= deny_mask; return (EACCES); + } else if (*working_mode) { + return (-1); + } return (0); } @@ -2390,10 +2434,10 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) working_mode &= ~(ACE_READ_ACL|ACE_READ_ATTRIBUTES); if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS| - ACE_READ_ACL|ACE_READ_ATTRIBUTES)) + ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE)) checkmode |= VREAD; if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS| - ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES)) + ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE)) checkmode |= VWRITE; if (working_mode & ACE_EXECUTE) checkmode |= VEXEC; @@ -2403,7 +2447,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) owner, checkmode); if (error == 0 && (working_mode & ACE_WRITE_OWNER)) - error = secpolicy_vnode_create_gid(cr); + error = secpolicy_vnode_chown(cr, B_TRUE); if (error == 0 && (working_mode & ACE_WRITE_ACL)) error = secpolicy_vnode_setdac(cr, owner); @@ -2411,9 +2455,9 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) (ACE_DELETE|ACE_DELETE_CHILD))) error = secpolicy_vnode_remove(cr); - if (error == 0 && (working_mode & ACE_SYNCHRONIZE)) - error = secpolicy_vnode_owner(cr, owner); - + if (error == 0 && (working_mode & ACE_SYNCHRONIZE)) { + error = secpolicy_vnode_chown(cr, B_FALSE); + } if (error == 0) { /* * See if any bits other than those already checked @@ -2533,10 +2577,10 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) return (EPERM); /* + * First row * If the directory permissions allow the delete, we are done. */ - if ((dzp_error = zfs_zaccess_common(dzp, - ACE_DELETE_CHILD|ACE_EXECUTE|ACE_WRITE_DATA, + if ((dzp_error = zfs_zaccess_common(dzp, ACE_DELETE_CHILD, &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr)) == 0) return (0); @@ -2547,54 +2591,49 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) &zpcheck_privs, B_FALSE, cr)) == 0) return (0); + ASSERT(dzp_error && zp_error); + if (!dzpcheck_privs) return (dzp_error); - else if (!zpcheck_privs) + if (!zpcheck_privs) return (zp_error); - /* - * First check the first row. - * We only need to see if parent Allows delete_child - */ - if ((dzp_working_mode & ACE_DELETE_CHILD) == 0) - return (0); - /* * Second row - * we already have the necessary information in - * zp_working_mode, zp_error and dzp_error. + * + * If directory returns EACCES then delete_child was denied + * due to deny delete_child. In this case send the request through + * secpolicy_vnode_remove(). We don't use zfs_delete_final_check() + * since that *could* allow the delete based on write/execute permission + * and we want delete permissions to override write/execute. */ - if ((zp_working_mode & ACE_DELETE) == 0) - return (0); - - /* - * determine the needed permissions based off of the directories - * working mode - */ - - missing_perms = (dzp_working_mode & ACE_WRITE_DATA) ? VWRITE : 0; - missing_perms |= (dzp_working_mode & ACE_EXECUTE) ? VEXEC : 0; - if (dzp_error == EACCES) - return (zfs_delete_final_check(zp, dzp, missing_perms, cr)); + return (secpolicy_vnode_remove(cr)); /* * Third Row * only need to see if we have write/execute on directory. */ - if (missing_perms == 0) + if ((dzp_error = zfs_zaccess_common(dzp, ACE_EXECUTE|ACE_WRITE_DATA, + &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr)) == 0) return (zfs_sticky_remove_access(dzp, zp, cr)); + if (!dzpcheck_privs) + return (dzp_error); + /* - * Fourth Row + * Fourth row */ - if (missing_perms && ((zp_working_mode & ACE_DELETE) == 0)) - return (zfs_sticky_remove_access(dzp, zp, cr)); + missing_perms = (dzp_working_mode & ACE_WRITE_DATA) ? VWRITE : 0; + missing_perms |= (dzp_working_mode & ACE_EXECUTE) ? VEXEC : 0; + + ASSERT(missing_perms); return (zfs_delete_final_check(zp, dzp, missing_perms, cr)); + } int diff --git a/zfs/lib/libzpool/zfs_byteswap.c b/zfs/lib/libzpool/zfs_byteswap.c index 2e98f84bb..ab97f83eb 100644 --- a/zfs/lib/libzpool/zfs_byteswap.c +++ b/zfs/lib/libzpool/zfs_byteswap.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_byteswap.c 1.3 07/10/25 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libdmu-ctl/zfs_ctldir.c b/zfs/lib/libzpool/zfs_ctldir.c similarity index 98% rename from zfs/lib/libdmu-ctl/zfs_ctldir.c rename to zfs/lib/libzpool/zfs_ctldir.c index 45de481c9..208fc3629 100644 --- a/zfs/lib/libdmu-ctl/zfs_ctldir.c +++ b/zfs/lib/libzpool/zfs_ctldir.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_ctldir.c 1.20 08/04/27 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * ZFS control directory (a.k.a. ".zfs") @@ -78,6 +78,8 @@ #include #include +#include "zfs_namecheck.h" + typedef struct zfsctl_node { gfs_dir_t zc_gfs_private; uint64_t zc_id; @@ -428,6 +430,8 @@ zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname) { objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os; + if (snapshot_namecheck(name, NULL, NULL) != 0) + return (EILSEQ); dmu_objset_name(os, zname); if (strlen(zname) + 1 + strlen(name) >= len) return (ENAMETOOLONG); @@ -655,6 +659,9 @@ zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, static enum symfollow follow = NO_FOLLOW; static enum uio_seg seg = UIO_SYSSPACE; + if (snapshot_namecheck(dirname, NULL, NULL) != 0) + return (EILSEQ); + dmu_objset_name(zfsvfs->z_os, name); *vpp = NULL; @@ -772,10 +779,15 @@ zfsctl_snapdir_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, if (err) { mutex_exit(&sdp->sd_lock); ZFS_EXIT(zfsvfs); - return (err); + /* + * handle "ls *" or "?" in a graceful manner, + * forcing EILSEQ to ENOENT. + * Since shell ultimately passes "*" or "?" as name to lookup + */ + return (err == EILSEQ ? ENOENT : err); } if (dmu_objset_open(snapname, DMU_OST_ZFS, - DS_MODE_STANDARD | DS_MODE_READONLY, &snap) != 0) { + DS_MODE_USER | DS_MODE_READONLY, &snap) != 0) { mutex_exit(&sdp->sd_lock); ZFS_EXIT(zfsvfs); return (ENOENT); diff --git a/zfs/lib/libdmu-ctl/zfs_dir.c b/zfs/lib/libzpool/zfs_dir.c similarity index 95% rename from zfs/lib/libdmu-ctl/zfs_dir.c rename to zfs/lib/libzpool/zfs_dir.c index 6f22e2ad1..1ec493264 100644 --- a/zfs/lib/libdmu-ctl/zfs_dir.c +++ b/zfs/lib/libzpool/zfs_dir.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_dir.c 1.25 08/04/27 SMI" - #include #include #include @@ -407,21 +405,6 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags, return (error); } -static char * -zfs_unlinked_hexname(char namebuf[17], uint64_t x) -{ - char *name = &namebuf[16]; - const char digits[16] = "0123456789abcdef"; - - *name = '\0'; - do { - *--name = digits[x & 0xf]; - x >>= 4; - } while (x != 0); - - return (name); -} - /* * unlinked Set (formerly known as the "delete queue") Error Handling * @@ -440,15 +423,12 @@ void zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx) { zfsvfs_t *zfsvfs = zp->z_zfsvfs; - char obj_name[17]; - int error; ASSERT(zp->z_unlinked); ASSERT3U(zp->z_phys->zp_links, ==, 0); - error = zap_add(zfsvfs->z_os, zfsvfs->z_unlinkedobj, - zfs_unlinked_hexname(obj_name, zp->z_id), 8, 1, &zp->z_id, tx); - ASSERT3U(error, ==, 0); + VERIFY3U(0, ==, + zap_add_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); } /* @@ -574,7 +554,6 @@ zfs_rmnode(znode_t *zp) zfsvfs_t *zfsvfs = zp->z_zfsvfs; objset_t *os = zfsvfs->z_os; znode_t *xzp = NULL; - char obj_name[17]; dmu_tx_t *tx; uint64_t acl_obj; int error; @@ -582,6 +561,24 @@ zfs_rmnode(znode_t *zp) ASSERT(ZTOV(zp)->v_count == 0); ASSERT(zp->z_phys->zp_links == 0); + /* + * If this is a ZIL replay then leave the object in the unlinked set. + * Otherwise we can get a deadlock, because the delete can be + * quite large and span multiple tx's and txgs, but each replay + * creates a tx to atomically run the replay function and mark the + * replay record as complete. We deadlock trying to start a tx in + * a new txg to further the deletion but can't because the replay + * tx hasn't finished. + * + * We actually delete the object if we get a failure to create an + * object in zil_replay_log_record(), or after calling zil_replay(). + */ + if (zfsvfs->z_assign >= TXG_INITIAL) { + zfs_znode_dmu_fini(zp); + zfs_znode_free(zp); + return; + } + /* * If this is an attribute directory, purge its contents. */ @@ -589,7 +586,7 @@ zfs_rmnode(znode_t *zp) if (zfs_purgedir(zp) != 0) { /* * Not enough space to delete some xattrs. - * Leave it on the unlinked set. + * Leave it in the unlinked set. */ zfs_znode_dmu_fini(zp); zfs_znode_free(zp); @@ -597,6 +594,19 @@ zfs_rmnode(znode_t *zp) } } + /* + * Free up all the data in the file. + */ + error = dmu_free_long_range(os, zp->z_id, 0, DMU_OBJECT_END); + if (error) { + /* + * Not enough space. Leave the file in the unlinked set. + */ + zfs_znode_dmu_fini(zp); + zfs_znode_free(zp); + return; + } + /* * If the file has extended attributes, we're going to unlink * the xattr dir. @@ -609,7 +619,7 @@ zfs_rmnode(znode_t *zp) acl_obj = zp->z_phys->zp_acl.z_acl_extern_obj; /* - * Set up the transaction. + * Set up the final transaction. */ tx = dmu_tx_create(os); dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END); @@ -643,9 +653,8 @@ zfs_rmnode(znode_t *zp) } /* Remove this znode from the unlinked set */ - error = zap_remove(os, zfsvfs->z_unlinkedobj, - zfs_unlinked_hexname(obj_name, zp->z_id), tx); - ASSERT3U(error, ==, 0); + VERIFY3U(0, ==, + zap_remove_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); zfs_znode_delete(zp, tx); diff --git a/zfs/lib/libzpool/zfs_fm.c b/zfs/lib/libzpool/zfs_fm.c index 4be77103f..236d69e7e 100644 --- a/zfs/lib/libzpool/zfs_fm.c +++ b/zfs/lib/libzpool/zfs_fm.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_fm.c 1.6 08/04/01 SMI" - #include #include #include @@ -48,7 +46,7 @@ * pool X * * If we are in a loading state, all errors are chained together by the same - * SPA-wide ENA. + * SPA-wide ENA (Error Numeric Association). * * For isolated I/O requests, we get the ENA from the zio_t. The propagation * gets very complicated due to RAID-Z, gang blocks, and vdev caching. We want @@ -85,11 +83,10 @@ * We keep track of the ENA for a ZIO chain through the 'io_logical' member. * When a new logical I/O is issued, we set this to point to itself. Child I/Os * then inherit this pointer, so that when it is first set subsequent failures - * will use the same ENA. If a physical I/O is issued (by passing the - * ZIO_FLAG_NOBOOKMARK flag), then this pointer is reset, guaranteeing that a - * unique ENA will be generated. For an aggregate I/O, this pointer is set to - * NULL, and no ereport will be generated (since it doesn't actually correspond - * to any particular device or piece of data). + * will use the same ENA. For vdev cache fill and queue aggregation I/O, + * this pointer is set to NULL, and no ereport will be generated (since it + * doesn't actually correspond to any particular device or piece of data, + * and the caller will always retry without caching or queueing anyway). */ void zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio, @@ -99,6 +96,7 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio, nvlist_t *ereport, *detector; uint64_t ena; char class[64]; + int state; /* * If we are doing a spa_tryimport(), ignore errors. @@ -115,22 +113,33 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio, spa->spa_last_open_failed) return; - /* - * Ignore any errors from I/Os that we are going to retry anyway - we - * only generate errors from the final failure. Checksum errors are - * generated after the pipeline stage responsible for retrying the I/O - * (VDEV_IO_ASSESS), so this only applies to standard I/O errors. - */ - if (zio && zio_should_retry(zio) && zio->io_error != ECKSUM) - return; + if (zio != NULL) { + /* + * If this is not a read or write zio, ignore the error. This + * can occur if the DKIOCFLUSHWRITECACHE ioctl fails. + */ + if (zio->io_type != ZIO_TYPE_READ && + zio->io_type != ZIO_TYPE_WRITE) + return; - /* - * If this is not a read or write zio, ignore the error. This can occur - * if the DKIOCFLUSHWRITECACHE ioctl fails. - */ - if (zio && zio->io_type != ZIO_TYPE_READ && - zio->io_type != ZIO_TYPE_WRITE) - return; + /* + * Ignore any errors from speculative I/Os, as failure is an + * expected result. + */ + if (zio->io_flags & ZIO_FLAG_SPECULATIVE) + return; + + /* + * If the vdev has already been marked as failing due to a + * failed probe, then ignore any subsequent I/O errors, as the + * DE will automatically fault the vdev on the first such + * failure. + */ + if (vd != NULL && + (!vdev_readable(vd) || !vdev_writeable(vd)) && + strcmp(subclass, FM_EREPORT_ZFS_PROBE_FAILURE) != 0) + return; + } if ((ereport = fm_nvlist_create(NULL)) == NULL) return; @@ -179,23 +188,32 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio, * passed in. */ + /* + * If we are importing a faulted pool, then we treat it like an open, + * not an import. Otherwise, the DE will ignore all faults during + * import, since the default behavior is to mark the devices as + * persistently unavailable, not leave them in the faulted state. + */ + state = spa->spa_import_faulted ? SPA_LOAD_OPEN : spa->spa_load_state; + /* * Generic payload members common to all ereports. - * - * The direct reference to spa_name is used rather than spa_name() - * because of the asynchronous nature of the zio pipeline. spa_name() - * asserts that the config lock is held in some form. This is always - * the case in I/O context, but because the check for RW_WRITER compares - * against 'curthread', we may be in an asynchronous context and blow - * this assert. Rather than loosen this assert, we acknowledge that all - * contexts in which this function is called (pool open, I/O) are safe, - * and dereference the name directly. */ fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_POOL, - DATA_TYPE_STRING, spa->spa_name, FM_EREPORT_PAYLOAD_ZFS_POOL_GUID, + DATA_TYPE_STRING, spa_name(spa), FM_EREPORT_PAYLOAD_ZFS_POOL_GUID, DATA_TYPE_UINT64, spa_guid(spa), FM_EREPORT_PAYLOAD_ZFS_POOL_CONTEXT, DATA_TYPE_INT32, - spa->spa_load_state, NULL); + state, NULL); + + if (spa != NULL) { + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_POOL_FAILMODE, + DATA_TYPE_STRING, + spa_get_failmode(spa) == ZIO_FAILURE_MODE_WAIT ? + FM_EREPORT_FAILMODE_WAIT : + spa_get_failmode(spa) == ZIO_FAILURE_MODE_CONTINUE ? + FM_EREPORT_FAILMODE_CONTINUE : FM_EREPORT_FAILMODE_PANIC, + NULL); + } if (vd != NULL) { vdev_t *pvd = vd->vdev_parent; @@ -320,17 +338,6 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *name) #endif } -/* - * The 'resource.fs.zfs.ok' event is an internal signal that the associated - * resource (pool or disk) has been identified by ZFS as healthy. This will - * then trigger the DE to close the associated case, if any. - */ -void -zfs_post_ok(spa_t *spa, vdev_t *vd) -{ - zfs_post_common(spa, vd, FM_RESOURCE_OK); -} - /* * The 'resource.fs.zfs.removed' event is an internal signal that the given vdev * has been removed from the system. This will cause the DE to ignore any diff --git a/zfs/lib/libdmu-ctl/zfs_fuid.c b/zfs/lib/libzpool/zfs_fuid.c similarity index 95% rename from zfs/lib/libdmu-ctl/zfs_fuid.c rename to zfs/lib/libzpool/zfs_fuid.c index 59c9adfe2..7cb505258 100644 --- a/zfs/lib/libdmu-ctl/zfs_fuid.c +++ b/zfs/lib/libzpool/zfs_fuid.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_fuid.c 1.5 08/01/31 SMI" - #include #include #include @@ -65,6 +63,8 @@ typedef struct fuid_domain { uint64_t f_idx; } fuid_domain_t; +static char *nulldomain = ""; + /* * Compare two indexes. */ @@ -181,7 +181,7 @@ zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx) findnode = avl_find(idx_tree, &searchnode, &loc); - return (findnode->f_ksid->kd_name); + return (findnode ? findnode->f_ksid->kd_name : nulldomain); } #ifdef _KERNEL @@ -216,10 +216,13 @@ zfs_fuid_init(zfsvfs_t *zfsvfs, dmu_tx_t *tx) } } - zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os, - zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain); + if (zfsvfs->z_fuid_obj != 0) { + zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os, + zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx, + &zfsvfs->z_fuid_domain); + zfsvfs->z_fuid_loaded = B_TRUE; + } - zfsvfs->z_fuid_loaded = B_TRUE; rw_exit(&zfsvfs->z_fuid_lock); } @@ -235,6 +238,7 @@ zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, char **retdomain, { fuid_domain_t searchnode, *findnode; avl_index_t loc; + krw_t rw = RW_READER; /* * If the dummy "nobody" domain then return an index of 0 @@ -242,7 +246,7 @@ zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, char **retdomain, * for the user nobody. */ if (domain[0] == '\0') { - *retdomain = ""; + *retdomain = nulldomain; return (0); } @@ -253,11 +257,12 @@ zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, char **retdomain, if (!zfsvfs->z_fuid_loaded) zfs_fuid_init(zfsvfs, tx); - rw_enter(&zfsvfs->z_fuid_lock, RW_READER); +retry: + rw_enter(&zfsvfs->z_fuid_lock, rw); findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc); - rw_exit(&zfsvfs->z_fuid_lock); if (findnode) { + rw_exit(&zfsvfs->z_fuid_lock); ksiddomain_rele(searchnode.f_ksid); return (findnode->f_idx); } else { @@ -270,10 +275,15 @@ zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, char **retdomain, dmu_buf_t *db; int i = 0; + if (rw == RW_READER && !rw_tryupgrade(&zfsvfs->z_fuid_lock)) { + rw_exit(&zfsvfs->z_fuid_lock); + rw = RW_WRITER; + goto retry; + } + domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP); domnode->f_ksid = searchnode.f_ksid; - rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER); retidx = domnode->f_idx = avl_numnodes(&zfsvfs->z_fuid_idx) + 1; avl_add(&zfsvfs->z_fuid_domain, domnode); @@ -339,7 +349,11 @@ zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx) zfs_fuid_init(zfsvfs, NULL); rw_enter(&zfsvfs->z_fuid_lock, RW_READER); - domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx); + + if (zfsvfs->z_fuid_obj) + domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx); + else + domain = nulldomain; rw_exit(&zfsvfs->z_fuid_lock); ASSERT(domain); @@ -460,17 +474,19 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, VERIFY(type == ZFS_OWNER || type == ZFS_GROUP); - if (type == ZFS_OWNER) - id = crgetuid(cr); - else - id = crgetgid(cr); + ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP); + if (ksid) { + id = ksid_getid(ksid); + } else { + if (type == ZFS_OWNER) + id = crgetuid(cr); + else + id = crgetgid(cr); + } - if (!zfsvfs->z_use_fuids || !IS_EPHEMERAL(id)) + if (!zfsvfs->z_use_fuids || (!IS_EPHEMERAL(id))) return ((uint64_t)id); - ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP); - - VERIFY(ksid != NULL); rid = ksid_getrid(ksid); domain = ksid_getdomain(ksid); @@ -562,7 +578,7 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr, * purposes. */ rid = UID_NOBODY; - domain = ""; + domain = nulldomain; } } diff --git a/zfs/lib/libdmu-ctl/zfs_ioctl.c b/zfs/lib/libzpool/zfs_ioctl.c similarity index 84% rename from zfs/lib/libdmu-ctl/zfs_ioctl.c rename to zfs/lib/libzpool/zfs_ioctl.c index e4d253474..b6ad57451 100644 --- a/zfs/lib/libdmu-ctl/zfs_ioctl.c +++ b/zfs/lib/libzpool/zfs_ioctl.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_ioctl.c 1.61 08/04/27 SMI" - #include #include #include @@ -92,6 +90,11 @@ typedef struct zfs_ioc_vec { boolean_t zvec_his_log; } zfs_ioc_vec_t; +static void clear_props(char *dataset, nvlist_t *props); +static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *, + boolean_t *); +int zfs_set_prop_nvlist(const char *, nvlist_t *); + /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */ void __dprintf(const char *file, const char *func, int line, const char *fmt, ...) @@ -155,14 +158,37 @@ history_str_get(zfs_cmd_t *zc) } /* - * zfs_check_version + * Check to see if the named dataset is currently defined as bootable + */ +static boolean_t +zfs_is_bootfs(const char *name) +{ + spa_t *spa; + boolean_t ret = B_FALSE; + + if (spa_open(name, &spa, FTAG) == 0) { + if (spa->spa_bootfs) { + objset_t *os; + + if (dmu_objset_open(name, DMU_OST_ZFS, + DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { + ret = (dmu_objset_id(os) == spa->spa_bootfs); + dmu_objset_close(os); + } + } + spa_close(spa, FTAG); + } + return (ret); +} + +/* + * zfs_earlier_version * * Return non-zero if the spa version is less than requested version. */ static int -zfs_check_version(const char *name, int version) +zfs_earlier_version(const char *name, int version) { - spa_t *spa; if (spa_open(name, &spa, FTAG) == 0) { @@ -176,24 +202,22 @@ zfs_check_version(const char *name, int version) } /* - * zpl_check_version + * zpl_earlier_version * - * Return non-zero if the ZPL version is less than requested version. + * Return TRUE if the ZPL version is less than requested version. */ -static int -zpl_check_version(const char *name, int version) +static boolean_t +zpl_earlier_version(const char *name, int version) { objset_t *os; - int rc = 1; + boolean_t rc = B_TRUE; if (dmu_objset_open(name, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &os) == 0) { - uint64_t propversion; + DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { + uint64_t zplversion; - if (zfs_get_zplprop(os, ZFS_PROP_VERSION, - &propversion) == 0) { - rc = !(propversion >= version); - } + if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0) + rc = zplversion < version; dmu_objset_close(os); } return (rc); @@ -494,7 +518,7 @@ zfs_secpolicy_promote(zfs_cmd_t *zc, cred_t *cr) return (error); error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &clone); + DS_MODE_USER | DS_MODE_READONLY, &clone); if (error == 0) { dsl_dataset_t *pclone = NULL; @@ -502,9 +526,8 @@ zfs_secpolicy_promote(zfs_cmd_t *zc, cred_t *cr) dd = clone->os->os_dsl_dataset->ds_dir; rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); - error = dsl_dataset_open_obj(dd->dd_pool, - dd->dd_phys->dd_origin_obj, NULL, - DS_MODE_NONE, FTAG, &pclone); + error = dsl_dataset_hold_obj(dd->dd_pool, + dd->dd_phys->dd_origin_obj, FTAG, &pclone); rw_exit(&dd->dd_pool->dp_config_rwlock); if (error) { dmu_objset_close(clone); @@ -516,7 +539,7 @@ zfs_secpolicy_promote(zfs_cmd_t *zc, cred_t *cr) dsl_dataset_name(pclone, parentname); dmu_objset_close(clone); - dsl_dataset_close(pclone, DS_MODE_NONE, FTAG); + dsl_dataset_rele(pclone, FTAG); if (error == 0) error = zfs_secpolicy_write_perms(parentname, ZFS_DELEG_PERM_PROMOTE, cr); @@ -721,6 +744,8 @@ zfs_ioc_pool_create(zfs_cmd_t *zc) { int error; nvlist_t *config, *props = NULL; + nvlist_t *rootprops = NULL; + nvlist_t *zplprops = NULL; char *buf; if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, @@ -733,17 +758,52 @@ zfs_ioc_pool_create(zfs_cmd_t *zc) return (error); } + if (props) { + nvlist_t *nvl = NULL; + uint64_t version = SPA_VERSION; + + (void) nvlist_lookup_uint64(props, + zpool_prop_to_name(ZPOOL_PROP_VERSION), &version); + if (version < SPA_VERSION_INITIAL || version > SPA_VERSION) { + error = EINVAL; + goto pool_props_bad; + } + (void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl); + if (nvl) { + error = nvlist_dup(nvl, &rootprops, KM_SLEEP); + if (error != 0) { + nvlist_free(config); + nvlist_free(props); + return (error); + } + (void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS); + } + VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0); + error = zfs_fill_zplprops_root(version, rootprops, + zplprops, NULL); + if (error) + goto pool_props_bad; + } + buf = history_str_get(zc); - error = spa_create(zc->zc_name, config, props, buf); + error = spa_create(zc->zc_name, config, props, buf, zplprops); + + /* + * Set the remaining root properties + */ + if (!error && + (error = zfs_set_prop_nvlist(zc->zc_name, rootprops)) != 0) + (void) spa_destroy(zc->zc_name); if (buf != NULL) history_str_free(buf); +pool_props_bad: + nvlist_free(rootprops); + nvlist_free(zplprops); nvlist_free(config); - - if (props) - nvlist_free(props); + nvlist_free(props); return (error); } @@ -777,6 +837,9 @@ zfs_ioc_pool_import(zfs_cmd_t *zc) if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 || guid != zc->zc_guid) error = EINVAL; + else if (zc->zc_cookie) + error = spa_import_faulted(zc->zc_name, config, + props); else error = spa_import(zc->zc_name, config, props); @@ -792,8 +855,10 @@ static int zfs_ioc_pool_export(zfs_cmd_t *zc) { int error; + boolean_t force = (boolean_t)zc->zc_cookie; + zfs_log_history(zc); - error = spa_export(zc->zc_name, NULL); + error = spa_export(zc->zc_name, NULL, force); return (error); } @@ -876,9 +941,7 @@ zfs_ioc_pool_scrub(zfs_cmd_t *zc) if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) return (error); - mutex_enter(&spa_namespace_lock); - error = spa_scrub(spa, zc->zc_cookie, B_FALSE); - mutex_exit(&spa_namespace_lock); + error = spa_scrub(spa, zc->zc_cookie); spa_close(spa, FTAG); @@ -969,9 +1032,8 @@ zfs_ioc_obj_to_path(zfs_cmd_t *zc) int error; if ((error = dmu_objset_open(zc->zc_name, DMU_OST_ZFS, - DS_MODE_NONE | DS_MODE_READONLY, &osp)) != 0) + DS_MODE_USER | DS_MODE_READONLY, &osp)) != 0) return (error); - error = zfs_obj_to_path(osp, zc->zc_obj, zc->zc_value, sizeof (zc->zc_value)); dmu_objset_close(osp); @@ -1123,30 +1185,6 @@ zfs_ioc_vdev_setpath(zfs_cmd_t *zc) return (error); } -static int -zfs_os_open_retry(char *name, objset_t **os) -{ - int error; - -retry: - error = dmu_objset_open(name, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, os); - if (error != 0) { - /* - * This is ugly: dmu_objset_open() can return EBUSY if - * the objset is held exclusively. Fortunately this hold is - * only for a short while, so we retry here. - * This avoids user code having to handle EBUSY, - * for example for a "zfs list". - */ - if (error == EBUSY) { - delay(1); - goto retry; - } - } - return (error); -} - /* * inputs: * zc_name name of filesystem @@ -1156,7 +1194,6 @@ retry: * zc_objset_stats stats * zc_nvlist_dst property nvlist * zc_nvlist_dst_size size of property nvlist - * zc_value alternate root */ static int zfs_ioc_objset_stats(zfs_cmd_t *zc) @@ -1165,18 +1202,19 @@ zfs_ioc_objset_stats(zfs_cmd_t *zc) int error; nvlist_t *nv; - if ((error = zfs_os_open_retry(zc->zc_name, &os)) != 0) + if (error = dmu_objset_open(zc->zc_name, + DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) return (error); dmu_objset_fast_stat(os, &zc->zc_objset_stats); if (zc->zc_nvlist_dst != 0 && - (error = dsl_prop_get_all(os, &nv)) == 0) { + (error = dsl_prop_get_all(os, &nv, FALSE)) == 0) { dmu_objset_stats(os, nv); /* * NB: zvol_get_stats() will read the objset contents, * which we aren't supposed to do with a - * DS_MODE_STANDARD open, because it could be + * DS_MODE_USER hold, because it could be * inconsistent. So this is a bit of a workaround... */ if (!zc->zc_objset_stats.dds_inconsistent) { @@ -1187,8 +1225,6 @@ zfs_ioc_objset_stats(zfs_cmd_t *zc) nvlist_free(nv); } - spa_altroot(dmu_objset_spa(os), zc->zc_value, sizeof (zc->zc_value)); - dmu_objset_close(os); return (error); } @@ -1224,15 +1260,16 @@ zfs_ioc_objset_zplprops(zfs_cmd_t *zc) objset_t *os; int err; - if ((err = zfs_os_open_retry(zc->zc_name, &os)) != 0) + if (err = dmu_objset_open(zc->zc_name, + DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) return (err); dmu_objset_fast_stat(os, &zc->zc_objset_stats); /* * NB: nvl_add_zplprop() will read the objset contents, - * which we aren't supposed to do with a DS_MODE_STANDARD - * open, because it could be inconsistent. + * which we aren't supposed to do with a DS_MODE_USER + * hold, because it could be inconsistent. */ if (zc->zc_nvlist_dst != NULL && !zc->zc_objset_stats.dds_inconsistent && @@ -1264,7 +1301,6 @@ zfs_ioc_objset_zplprops(zfs_cmd_t *zc) * zc_objset_stats stats * zc_nvlist_dst property nvlist * zc_nvlist_dst_size size of property nvlist - * zc_value alternate root */ static int zfs_ioc_dataset_list_next(zfs_cmd_t *zc) @@ -1273,7 +1309,8 @@ zfs_ioc_dataset_list_next(zfs_cmd_t *zc) int error; char *p; - if ((error = zfs_os_open_retry(zc->zc_name, &os)) != 0) { + if (error = dmu_objset_open(zc->zc_name, + DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) { if (error == ENOENT) error = ESRCH; return (error); @@ -1292,6 +1329,7 @@ zfs_ioc_dataset_list_next(zfs_cmd_t *zc) error = ESRCH; } while (error == 0 && !INGLOBALZONE(curproc) && !zone_dataset_visible(zc->zc_name, NULL)); + dmu_objset_close(os); /* * If it's a hidden dataset (ie. with a '$' in its name), don't @@ -1300,7 +1338,6 @@ zfs_ioc_dataset_list_next(zfs_cmd_t *zc) if (error == 0 && strchr(zc->zc_name, '$') == NULL) error = zfs_ioc_objset_stats(zc); /* fill in the stats */ - dmu_objset_close(os); return (error); } @@ -1315,7 +1352,6 @@ zfs_ioc_dataset_list_next(zfs_cmd_t *zc) * zc_objset_stats stats * zc_nvlist_dst property nvlist * zc_nvlist_dst_size size of property nvlist - * zc_value alternate root */ static int zfs_ioc_snapshot_list_next(zfs_cmd_t *zc) @@ -1323,11 +1359,10 @@ zfs_ioc_snapshot_list_next(zfs_cmd_t *zc) objset_t *os; int error; - if ((error = zfs_os_open_retry(zc->zc_name, &os)) != 0) { - if (error == ENOENT) - error = ESRCH; - return (error); - } + error = dmu_objset_open(zc->zc_name, + DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os); + if (error) + return (error == ENOENT ? ESRCH : error); /* * A dataset name of maximum length cannot have any snapshots, @@ -1341,17 +1376,15 @@ zfs_ioc_snapshot_list_next(zfs_cmd_t *zc) error = dmu_snapshot_list_next(os, sizeof (zc->zc_name) - strlen(zc->zc_name), zc->zc_name + strlen(zc->zc_name), NULL, &zc->zc_cookie, NULL); - if (error == ENOENT) - error = ESRCH; - + dmu_objset_close(os); if (error == 0) error = zfs_ioc_objset_stats(zc); /* fill in the stats */ + else if (error == ENOENT) + error = ESRCH; /* if we failed, undo the @ that we tacked on to zc_name */ - if (error != 0) + if (error) *strchr(zc->zc_name, '@') = '\0'; - - dmu_objset_close(os); return (error); } @@ -1400,27 +1433,45 @@ zfs_set_prop_nvlist(const char *name, nvlist_t *nvl) * we'll catch them later. */ if (nvpair_type(elem) == DATA_TYPE_UINT64 && - nvpair_value_uint64(elem, &intval) == 0 && - intval >= ZIO_COMPRESS_GZIP_1 && - intval <= ZIO_COMPRESS_GZIP_9) { - if (zfs_check_version(name, + nvpair_value_uint64(elem, &intval) == 0) { + if (intval >= ZIO_COMPRESS_GZIP_1 && + intval <= ZIO_COMPRESS_GZIP_9 && + zfs_earlier_version(name, SPA_VERSION_GZIP_COMPRESSION)) return (ENOTSUP); + + /* + * If this is a bootable dataset then + * verify that the compression algorithm + * is supported for booting. We must return + * something other than ENOTSUP since it + * implies a downrev pool version. + */ + if (zfs_is_bootfs(name) && + !BOOTFS_COMPRESS_VALID(intval)) + return (ERANGE); } break; case ZFS_PROP_COPIES: - if (zfs_check_version(name, SPA_VERSION_DITTO_BLOCKS)) + if (zfs_earlier_version(name, + SPA_VERSION_DITTO_BLOCKS)) return (ENOTSUP); break; case ZFS_PROP_SHARESMB: - if (zpl_check_version(name, ZPL_VERSION_FUID)) + if (zpl_earlier_version(name, ZPL_VERSION_FUID)) return (ENOTSUP); break; + + case ZFS_PROP_ACLINHERIT: + if (nvpair_type(elem) == DATA_TYPE_UINT64 && + nvpair_value_uint64(elem, &intval) == 0) + if (intval == ZFS_ACL_PASSTHROUGH_X && + zfs_earlier_version(name, + SPA_VERSION_PASSTHROUGH_X)) + return (ENOTSUP); } - if ((error = zfs_secpolicy_setprop(name, prop, CRED())) != 0) - return (error); } elem = NULL; @@ -1533,6 +1584,7 @@ zfs_set_prop_nvlist(const char *name, nvlist_t *nvl) * zc_name name of filesystem * zc_value name of property to inherit * zc_nvlist_src{_size} nvlist of properties to apply + * zc_cookie clear existing local props? * * outputs: none */ @@ -1546,6 +1598,21 @@ zfs_ioc_set_prop(zfs_cmd_t *zc) &nvl)) != 0) return (error); + if (zc->zc_cookie) { + nvlist_t *origprops; + objset_t *os; + + if (dmu_objset_open(zc->zc_name, DMU_OST_ANY, + DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { + if (dsl_prop_get_all(os, &origprops, TRUE) == 0) { + clear_props(zc->zc_name, origprops); + nvlist_free(origprops); + } + dmu_objset_close(os); + } + + } + error = zfs_set_prop_nvlist(zc->zc_name, nvl); nvlist_free(nvl); @@ -1794,11 +1861,14 @@ zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx) /* * inputs: - * createprops list of properties requested by creator - * dataset name of dataset we are creating + * createprops list of properties requested by creator + * default_zplver zpl version to use if unspecified in createprops + * fuids_ok fuids allowed in this version of the spa? + * os parent objset pointer (NULL if root fs) * * outputs: * zplprops values for the zplprops we attach to the master node object + * is_ci true if requested file system will be purely case-insensitive * * Determine the settings for utf8only, normalization and * casesensitivity. Specific values may have been requested by the @@ -1810,28 +1880,23 @@ zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx) * processing. */ static int -zfs_fill_zplprops(const char *dataset, nvlist_t *createprops, - nvlist_t *zplprops, uint64_t zplver, boolean_t *is_ci) +zfs_fill_zplprops_impl(objset_t *os, uint64_t default_zplver, + boolean_t fuids_ok, nvlist_t *createprops, nvlist_t *zplprops, + boolean_t *is_ci) { - objset_t *os; - char parentname[MAXNAMELEN]; - char *cp; + uint64_t zplver = default_zplver; uint64_t sense = ZFS_PROP_UNDEFINED; uint64_t norm = ZFS_PROP_UNDEFINED; uint64_t u8 = ZFS_PROP_UNDEFINED; - int error = 0; ASSERT(zplprops != NULL); - (void) strlcpy(parentname, dataset, sizeof (parentname)); - cp = strrchr(parentname, '/'); - ASSERT(cp != NULL); - cp[0] = '\0'; - /* * Pull out creator prop choices, if any. */ if (createprops) { + (void) nvlist_lookup_uint64(createprops, + zfs_prop_to_name(ZFS_PROP_VERSION), &zplver); (void) nvlist_lookup_uint64(createprops, zfs_prop_to_name(ZFS_PROP_NORMALIZE), &norm); (void) nvlist_remove_all(createprops, @@ -1847,15 +1912,16 @@ zfs_fill_zplprops(const char *dataset, nvlist_t *createprops, } /* - * If the file system or pool is version is too "young" to - * support normalization and the creator tried to set a value - * for one of the props, error out. We only need check the - * ZPL version because we've already checked by now that the - * SPA version is compatible with the selected ZPL version. + * If the zpl version requested is whacky or the file system + * or pool is version is too "young" to support normalization + * and the creator tried to set a value for one of the props, + * error out. */ - if (zplver < ZPL_VERSION_NORMALIZATION && + if ((zplver < ZPL_VERSION_INITIAL || zplver > ZPL_VERSION) || + (zplver >= ZPL_VERSION_FUID && !fuids_ok) || + (zplver < ZPL_VERSION_NORMALIZATION && (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED || - sense != ZFS_PROP_UNDEFINED)) + sense != ZFS_PROP_UNDEFINED))) return (ENOTSUP); /* @@ -1864,13 +1930,6 @@ zfs_fill_zplprops(const char *dataset, nvlist_t *createprops, VERIFY(nvlist_add_uint64(zplprops, zfs_prop_to_name(ZFS_PROP_VERSION), zplver) == 0); - /* - * Open parent object set so we can inherit zplprop values if - * necessary. - */ - if ((error = zfs_os_open_retry(parentname, &os)) != 0) - return (error); - if (norm == ZFS_PROP_UNDEFINED) VERIFY(zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &norm) == 0); VERIFY(nvlist_add_uint64(zplprops, @@ -1894,10 +1953,61 @@ zfs_fill_zplprops(const char *dataset, nvlist_t *createprops, if (is_ci) *is_ci = (sense == ZFS_CASE_INSENSITIVE); - dmu_objset_close(os); return (0); } +static int +zfs_fill_zplprops(const char *dataset, nvlist_t *createprops, + nvlist_t *zplprops, boolean_t *is_ci) +{ + boolean_t fuids_ok = B_TRUE; + uint64_t zplver = ZPL_VERSION; + objset_t *os = NULL; + char parentname[MAXNAMELEN]; + char *cp; + int error; + + (void) strlcpy(parentname, dataset, sizeof (parentname)); + cp = strrchr(parentname, '/'); + ASSERT(cp != NULL); + cp[0] = '\0'; + + if (zfs_earlier_version(dataset, SPA_VERSION_FUID)) { + zplver = ZPL_VERSION_FUID - 1; + fuids_ok = B_FALSE; + } + + /* + * Open parent object set so we can inherit zplprop values. + */ + if ((error = dmu_objset_open(parentname, DMU_OST_ANY, + DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) + return (error); + + error = zfs_fill_zplprops_impl(os, zplver, fuids_ok, createprops, + zplprops, is_ci); + dmu_objset_close(os); + return (error); +} + +static int +zfs_fill_zplprops_root(uint64_t spa_vers, nvlist_t *createprops, + nvlist_t *zplprops, boolean_t *is_ci) +{ + boolean_t fuids_ok = B_TRUE; + uint64_t zplver = ZPL_VERSION; + int error; + + if (spa_vers < SPA_VERSION_FUID) { + zplver = ZPL_VERSION_FUID - 1; + fuids_ok = B_FALSE; + } + + error = zfs_fill_zplprops_impl(NULL, zplver, fuids_ok, createprops, + zplprops, is_ci); + return (error); +} + /* * inputs: * zc_objset_type type of objset to create (fs vs zvol) @@ -1954,7 +2064,7 @@ zfs_ioc_create(zfs_cmd_t *zc) } error = dmu_objset_open(zc->zc_value, type, - DS_MODE_STANDARD | DS_MODE_READONLY, &clone); + DS_MODE_USER | DS_MODE_READONLY, &clone); if (error) { nvlist_free(nvprops); return (error); @@ -2006,36 +2116,8 @@ zfs_ioc_create(zfs_cmd_t *zc) return (error); } } else if (type == DMU_OST_ZFS) { - uint64_t version; int error; - /* - * Default ZPL version to non-FUID capable if the - * pool is not upgraded to support FUIDs. - */ - if (zfs_check_version(zc->zc_name, SPA_VERSION_FUID)) - version = ZPL_VERSION_FUID - 1; - else - version = ZPL_VERSION; - - /* - * Potentially override default ZPL version based - * on creator's request. - */ - (void) nvlist_lookup_uint64(nvprops, - zfs_prop_to_name(ZFS_PROP_VERSION), &version); - - /* - * Make sure version we ended up with is kosher - */ - if ((version < ZPL_VERSION_INITIAL || - version > ZPL_VERSION) || - (version >= ZPL_VERSION_FUID && - zfs_check_version(zc->zc_name, SPA_VERSION_FUID))) { - nvlist_free(nvprops); - return (ENOTSUP); - } - /* * We have to have normalization and * case-folding flags correct when we do the @@ -2045,7 +2127,7 @@ zfs_ioc_create(zfs_cmd_t *zc) VERIFY(nvlist_alloc(&zct.zct_zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0); error = zfs_fill_zplprops(zc->zc_name, nvprops, - zct.zct_zplprops, version, &is_insensitive); + zct.zct_zplprops, &is_insensitive); if (error != 0) { nvlist_free(nvprops); nvlist_free(zct.zct_zplprops); @@ -2068,6 +2150,27 @@ zfs_ioc_create(zfs_cmd_t *zc) return (error); } +struct snap_prop_arg { + nvlist_t *nvprops; + const char *snapname; +}; + +static int +set_snap_props(char *name, void *arg) +{ + struct snap_prop_arg *snpa = arg; + int len = strlen(name) + strlen(snpa->snapname) + 2; + char *buf = kmem_alloc(len, KM_SLEEP); + int err; + + (void) snprintf(buf, len, "%s@%s", name, snpa->snapname); + err = zfs_set_prop_nvlist(buf, snpa->nvprops); + if (err) + (void) dmu_objset_destroy(buf); + kmem_free(buf, len); + return (err); +} + /* * inputs: * zc_name name of filesystem @@ -2079,30 +2182,57 @@ zfs_ioc_create(zfs_cmd_t *zc) static int zfs_ioc_snapshot(zfs_cmd_t *zc) { + nvlist_t *nvprops = NULL; + int error; + boolean_t recursive = zc->zc_cookie; + if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0) return (EINVAL); - return (dmu_objset_snapshot(zc->zc_name, - zc->zc_value, zc->zc_cookie)); + + if (zc->zc_nvlist_src != NULL && + (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, + &nvprops)) != 0) + return (error); + + error = dmu_objset_snapshot(zc->zc_name, zc->zc_value, recursive); + + /* + * It would be nice to do this atomically. + */ + if (error == 0) { + struct snap_prop_arg snpa; + snpa.nvprops = nvprops; + snpa.snapname = zc->zc_value; + if (recursive) { + error = dmu_objset_find(zc->zc_name, + set_snap_props, &snpa, DS_FIND_CHILDREN); + if (error) { + (void) dmu_snapshots_destroy(zc->zc_name, + zc->zc_value); + } + } else { + error = set_snap_props(zc->zc_name, &snpa); + } + } + nvlist_free(nvprops); + return (error); } int zfs_unmount_snap(char *name, void *arg) { - char *snapname = arg; - char *cp; vfs_t *vfsp = NULL; - /* - * Snapshots (which are under .zfs control) must be unmounted - * before they can be destroyed. - */ + if (arg) { + char *snapname = arg; + int len = strlen(name) + strlen(snapname) + 2; + char *buf = kmem_alloc(len, KM_SLEEP); - if (snapname) { - (void) strcat(name, "@"); - (void) strcat(name, snapname); - vfsp = zfs_get_vfs(name); - cp = strchr(name, '@'); - *cp = '\0'; + (void) strcpy(buf, name); + (void) strcat(buf, "@"); + (void) strcat(buf, snapname); + vfsp = zfs_get_vfs(buf); + kmem_free(buf, len); } else if (strchr(name, '@')) { vfsp = zfs_get_vfs(name); } @@ -2183,8 +2313,7 @@ zfs_ioc_rollback(zfs_cmd_t *zc) * won't be one if we're operating on a zvol, if the * objset doesn't exist yet, or is not mounted. */ - error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, - DS_MODE_STANDARD, &os); + error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, DS_MODE_USER, &os); if (error) return (error); @@ -2197,9 +2326,10 @@ zfs_ioc_rollback(zfs_cmd_t *zc) } if (zfsvfs != NULL) { - char osname[MAXNAMELEN]; + char *osname; int mode; + osname = kmem_alloc(MAXNAMELEN, KM_SLEEP); error = zfs_suspend_fs(zfsvfs, osname, &mode); if (error == 0) { int resume_err; @@ -2211,11 +2341,12 @@ zfs_ioc_rollback(zfs_cmd_t *zc) } else { dmu_objset_close(os); } + kmem_free(osname, MAXNAMELEN); VFS_RELE(zfsvfs->z_vfs); } else { error = dmu_objset_rollback(os); } - /* Note, the dmu_objset_rollback() closes the objset for us. */ + /* Note, the dmu_objset_rollback() releases the objset for us. */ return (error); } @@ -2249,10 +2380,28 @@ zfs_ioc_rename(zfs_cmd_t *zc) if (err) return (err); } - return (dmu_objset_rename(zc->zc_name, zc->zc_value, recursive)); } +static void +clear_props(char *dataset, nvlist_t *props) +{ + zfs_cmd_t *zc; + nvpair_t *prop; + + if (props == NULL) + return; + zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP); + (void) strcpy(zc->zc_name, dataset); + for (prop = nvlist_next_nvpair(props, NULL); prop; + prop = nvlist_next_nvpair(props, prop)) { + (void) strcpy(zc->zc_value, nvpair_name(prop)); + if (zfs_secpolicy_inherit(zc, CRED()) == 0) + (void) zfs_ioc_inherit_prop(zc); + } + kmem_free(zc, sizeof (zfs_cmd_t)); +} + /* * inputs: * zc_name name of containing filesystem @@ -2277,6 +2426,7 @@ zfs_ioc_recv(zfs_cmd_t *zc) int error, fd; offset_t off; nvlist_t *props = NULL; + nvlist_t *origprops = NULL; objset_t *origin = NULL; char *tosnap; char tofs[ZFS_MAXNAMELEN]; @@ -2303,133 +2453,104 @@ zfs_ioc_recv(zfs_cmd_t *zc) return (EBADF); } - /* - * Get the zfsvfs for the receiving objset. There - * won't be one if we're operating on a zvol, if the - * objset doesn't exist yet, or is not mounted. - */ - - error = dmu_objset_open(tofs, DMU_OST_ZFS, - DS_MODE_STANDARD | DS_MODE_READONLY, &os); - if (!error) { + if (dmu_objset_open(tofs, DMU_OST_ANY, + DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { + /* + * Try to get the zfsvfs for the receiving objset. + * There won't be one if we're operating on a zvol, + * if the objset doesn't exist yet, or is not mounted. + */ mutex_enter(&os->os->os_user_ptr_lock); - zfsvfs = dmu_objset_get_user(os); - if (zfsvfs != NULL) { - VFS_HOLD(zfsvfs->z_vfs); - mutex_exit(&os->os->os_user_ptr_lock); + if (zfsvfs = dmu_objset_get_user(os)) { if (!mutex_tryenter(&zfsvfs->z_online_recv_lock)) { - VFS_RELE(zfsvfs->z_vfs); + mutex_exit(&os->os->os_user_ptr_lock); dmu_objset_close(os); - nvlist_free(props); - releasef(fd); - return (EBUSY); + zfsvfs = NULL; + error = EBUSY; + goto out; } - } else { - mutex_exit(&os->os->os_user_ptr_lock); + VFS_HOLD(zfsvfs->z_vfs); } + mutex_exit(&os->os->os_user_ptr_lock); + + /* + * If new properties are supplied, they are to completely + * replace the existing ones, so stash away the existing ones. + */ + if (props) + (void) dsl_prop_get_all(os, &origprops, TRUE); + dmu_objset_close(os); } if (zc->zc_string[0]) { error = dmu_objset_open(zc->zc_string, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &origin); - if (error) { - if (zfsvfs != NULL) { - mutex_exit(&zfsvfs->z_online_recv_lock); - VFS_RELE(zfsvfs->z_vfs); - } - nvlist_free(props); - releasef(fd); - return (error); - } + DS_MODE_USER | DS_MODE_READONLY, &origin); + if (error) + goto out; } error = dmu_recv_begin(tofs, tosnap, &zc->zc_begin_record, force, origin, zfsvfs != NULL, &drc); if (origin) dmu_objset_close(origin); - if (error) { - if (zfsvfs != NULL) { - mutex_exit(&zfsvfs->z_online_recv_lock); - VFS_RELE(zfsvfs->z_vfs); - } - nvlist_free(props); - releasef(fd); - return (error); - } + if (error) + goto out; /* - * If properties are supplied, they are to completely replace - * the existing ones; "inherit" any existing properties. + * Reset properties. We do this before we receive the stream + * so that the properties are applied to the new data. */ if (props) { - objset_t *os; - nvlist_t *nv = NULL; - - error = dmu_objset_open(tofs, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY | DS_MODE_INCONSISTENT, - &os); - if (error == 0) { - error = dsl_prop_get_all(os, &nv); - dmu_objset_close(os); - } - if (error == 0) { - nvpair_t *elem; - zfs_cmd_t *zc2; - zc2 = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP); - - (void) strcpy(zc2->zc_name, tofs); - for (elem = nvlist_next_nvpair(nv, NULL); elem; - elem = nvlist_next_nvpair(nv, elem)) { - (void) strcpy(zc2->zc_value, nvpair_name(elem)); - if (zfs_secpolicy_inherit(zc2, CRED()) == 0) - (void) zfs_ioc_inherit_prop(zc2); - } - kmem_free(zc2, sizeof (zfs_cmd_t)); - } - if (nv) - nvlist_free(nv); + clear_props(tofs, origprops); + /* + * XXX - Note, this is all-or-nothing; should be best-effort. + */ + (void) zfs_set_prop_nvlist(tofs, props); } - /* - * Set properties. Note, we ignore errors. Would be better to - * do best-effort in zfs_set_prop_nvlist, too. - */ - (void) zfs_set_prop_nvlist(tofs, props); - nvlist_free(props); - off = fp->f_offset; error = dmu_recv_stream(&drc, fp->f_vnode, &off); - if (error == 0) { - if (zfsvfs != NULL) { - char osname[MAXNAMELEN]; - int mode; + if (error == 0 && zfsvfs) { + char *osname; + int mode; - error = zfs_suspend_fs(zfsvfs, osname, &mode); - if (error == 0) { - int resume_err; + /* online recv */ + osname = kmem_alloc(MAXNAMELEN, KM_SLEEP); + error = zfs_suspend_fs(zfsvfs, osname, &mode); + if (error == 0) { + int resume_err; - error = dmu_recv_end(&drc); - resume_err = zfs_resume_fs(zfsvfs, - osname, mode); - error = error ? error : resume_err; - } else { - dmu_recv_abort_cleanup(&drc); - } - } else { error = dmu_recv_end(&drc); + resume_err = zfs_resume_fs(zfsvfs, osname, mode); + error = error ? error : resume_err; + } else { + dmu_recv_abort_cleanup(&drc); } - } - if (zfsvfs != NULL) { - mutex_exit(&zfsvfs->z_online_recv_lock); - VFS_RELE(zfsvfs->z_vfs); + kmem_free(osname, MAXNAMELEN); + } else if (error == 0) { + error = dmu_recv_end(&drc); } zc->zc_cookie = off - fp->f_offset; if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0) fp->f_offset = off; + /* + * On error, restore the original props. + */ + if (error && props) { + clear_props(tofs, props); + (void) zfs_set_prop_nvlist(tofs, origprops); + } +out: + if (zfsvfs) { + mutex_exit(&zfsvfs->z_online_recv_lock); + VFS_RELE(zfsvfs->z_vfs); + } + nvlist_free(props); + nvlist_free(origprops); releasef(fd); return (error); } @@ -2453,21 +2574,23 @@ zfs_ioc_send(zfs_cmd_t *zc) offset_t off; error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &tosnap); + DS_MODE_USER | DS_MODE_READONLY, &tosnap); if (error) return (error); if (zc->zc_value[0] != '\0') { - char buf[MAXPATHLEN]; + char *buf; char *cp; - (void) strncpy(buf, zc->zc_name, sizeof (buf)); + buf = kmem_alloc(MAXPATHLEN, KM_SLEEP); + (void) strncpy(buf, zc->zc_name, MAXPATHLEN); cp = strchr(buf, '@'); if (cp) *(cp+1) = 0; - (void) strncat(buf, zc->zc_value, sizeof (buf)); + (void) strncat(buf, zc->zc_value, MAXPATHLEN); error = dmu_objset_open(buf, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &fromsnap); + DS_MODE_USER | DS_MODE_READONLY, &fromsnap); + kmem_free(buf, MAXPATHLEN); if (error) { dmu_objset_close(tosnap); return (error); @@ -2555,53 +2678,47 @@ zfs_ioc_clear(zfs_cmd_t *zc) { spa_t *spa; vdev_t *vd; - uint64_t txg; int error; + /* + * On zpool clear we also fix up missing slogs + */ + mutex_enter(&spa_namespace_lock); + spa = spa_lookup(zc->zc_name); + if (spa == NULL) { + mutex_exit(&spa_namespace_lock); + return (EIO); + } + if (spa->spa_log_state == SPA_LOG_MISSING) { + /* we need to let spa_open/spa_load clear the chains */ + spa->spa_log_state = SPA_LOG_CLEAR; + } + mutex_exit(&spa_namespace_lock); + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) return (error); - /* - * Try to resume any I/Os which may have been suspended - * as a result of a complete pool failure. - */ - if (!list_is_empty(&spa->spa_zio_list)) { - if (zio_vdev_resume_io(spa) != 0) { - spa_close(spa, FTAG); - return (EIO); - } - } - - txg = spa_vdev_enter(spa); + spa_vdev_state_enter(spa); if (zc->zc_guid == 0) { vd = NULL; - } else if ((vd = spa_lookup_by_guid(spa, zc->zc_guid)) == NULL) { - spa_aux_vdev_t *sav; - int i; - - /* - * Check if this is an l2cache device. - */ - ASSERT(spa != NULL); - sav = &spa->spa_l2cache; - for (i = 0; i < sav->sav_count; i++) { - if (sav->sav_vdevs[i]->vdev_guid == zc->zc_guid) { - vd = sav->sav_vdevs[i]; - break; - } - } - + } else { + vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE); if (vd == NULL) { - (void) spa_vdev_exit(spa, NULL, txg, ENODEV); + (void) spa_vdev_state_exit(spa, NULL, ENODEV); spa_close(spa, FTAG); return (ENODEV); } } - vdev_clear(spa, vd, B_TRUE); + vdev_clear(spa, vd); - (void) spa_vdev_exit(spa, NULL, txg, 0); + (void) spa_vdev_state_exit(spa, NULL, 0); + + /* + * Resume any suspended I/Os. + */ + zio_resume(spa); spa_close(spa, FTAG); @@ -2974,12 +3091,15 @@ static struct dev_ops zfs_dev_ops = { zfs_detach, /* detach */ nodev, /* reset */ &zfs_cb_ops, /* driver operations */ - NULL /* no bus operations */ + NULL, /* no bus operations */ + NULL, /* power */ + ddi_quiesce_not_needed, /* quiesce */ }; static struct modldrv zfs_modldrv = { - &mod_driverops, "ZFS storage pool version " SPA_VERSION_STRING, - &zfs_dev_ops + &mod_driverops, + "ZFS storage pool", + &zfs_dev_ops }; static struct modlinkage modlinkage = { diff --git a/zfs/lib/libdmu-ctl/zfs_log.c b/zfs/lib/libzpool/zfs_log.c similarity index 95% rename from zfs/lib/libdmu-ctl/zfs_log.c rename to zfs/lib/libzpool/zfs_log.c index 364385808..11cd4c264 100644 --- a/zfs/lib/libdmu-ctl/zfs_log.c +++ b/zfs/lib/libzpool/zfs_log.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_log.c 1.13 08/04/09 SMI" - #include #include #include @@ -227,7 +225,6 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, xvattr_t *xvap = (xvattr_t *)vap; void *end; size_t lrsize; - size_t namesize = strlen(name) + 1; size_t fuidsz = 0; @@ -458,10 +455,16 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, * Writes are handled in three different ways: * * WR_INDIRECT: - * If the write is greater than zfs_immediate_write_sz and there are - * no separate logs in this pool then later *if* we need to log the - * write then dmu_sync() is used to immediately write the block and - * its block pointer is put in the log record. + * In this mode, if we need to commit the write later, then the block + * is immediately written into the file system (using dmu_sync), + * and a pointer to the block is put into the log record. + * When the txg commits the block is linked in. + * This saves additionally writing the data into the log record. + * There are a few requirements for this to occur: + * - write is greater than zfs_immediate_write_sz + * - not using slogs (as slogs are assumed to always be faster + * than writing into the main pool) + * - the write occupies only one block * WR_COPIED: * If we know we'll immediately be committing the * transaction (FSYNC or FDSYNC), the we allocate a larger @@ -472,7 +475,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, * we retrieve the data using the dmu. */ slogging = spa_has_slogs(zilog->zl_spa); - if (resid > zfs_immediate_write_sz && !slogging) + if (resid > zfs_immediate_write_sz && !slogging && resid <= zp->z_blksz) write_state = WR_INDIRECT; else if (ioflag & (FSYNC | FDSYNC)) write_state = WR_COPIED; @@ -489,11 +492,9 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, ssize_t len; /* - * If there are slogs and the write would overflow the largest - * block, then because we don't want to use the main pool - * to dmu_sync, we have to split the write. + * If the write would overflow the largest block then split it. */ - if (slogging && resid > ZIL_MAX_LOG_DATA) + if (write_state != WR_INDIRECT && resid > ZIL_MAX_LOG_DATA) len = SPA_MAXBLOCKSIZE >> 1; else len = resid; @@ -640,7 +641,10 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, size_t txsize; size_t aclbytes = vsecp->vsa_aclentsz; - txtype = (zp->z_zfsvfs->z_version == ZPL_VERSION_INITIAL) ? + if (zilog == NULL || zp->z_unlinked) + return; + + txtype = (zp->z_zfsvfs->z_version < ZPL_VERSION_FUID) ? TX_ACL_V0 : TX_ACL; if (txtype == TX_ACL) @@ -648,13 +652,10 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, else lrsize = sizeof (*lrv0); - if (zilog == NULL || zp->z_unlinked) - return; - txsize = lrsize + ((txtype == TX_ACL) ? ZIL_ACE_LENGTH(aclbytes) : aclbytes) + (fuidp ? fuidp->z_domain_str_sz : 0) + - sizeof (uint64) * (fuidp ? fuidp->z_fuid_cnt : 0); + sizeof (uint64_t) * (fuidp ? fuidp->z_fuid_cnt : 0); itx = zil_itx_create(txtype, txsize); diff --git a/zfs/lib/libdmu-ctl/zfs_replay.c b/zfs/lib/libzpool/zfs_replay.c similarity index 99% rename from zfs/lib/libdmu-ctl/zfs_replay.c rename to zfs/lib/libzpool/zfs_replay.c index ca9990d7c..85b79703a 100644 --- a/zfs/lib/libdmu-ctl/zfs_replay.c +++ b/zfs/lib/libzpool/zfs_replay.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_replay.c 1.7 08/01/14 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -770,6 +770,8 @@ zfs_replay_acl_v0(zfsvfs_t *zfsvfs, lr_acl_v0_t *lr, boolean_t byteswap) bzero(&vsa, sizeof (vsa)); vsa.vsa_mask = VSA_ACE | VSA_ACECNT; vsa.vsa_aclcnt = lr->lr_aclcnt; + vsa.vsa_aclentsz = sizeof (ace_t) * vsa.vsa_aclcnt; + vsa.vsa_aclflags = 0; vsa.vsa_aclentp = ace; error = VOP_SETSECATTR(ZTOV(zp), &vsa, 0, kcred, NULL); diff --git a/zfs/lib/libdmu-ctl/zfs_rlock.c b/zfs/lib/libzpool/zfs_rlock.c similarity index 99% rename from zfs/lib/libdmu-ctl/zfs_rlock.c rename to zfs/lib/libzpool/zfs_rlock.c index 44ec73b5d..f0a75b5fa 100644 --- a/zfs/lib/libdmu-ctl/zfs_rlock.c +++ b/zfs/lib/libzpool/zfs_rlock.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_rlock.c 1.4 07/08/08 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * This file contains the code to implement file range locking in diff --git a/zfs/lib/libdmu-ctl/zfs_vfsops.c b/zfs/lib/libzpool/zfs_vfsops.c similarity index 94% rename from zfs/lib/libdmu-ctl/zfs_vfsops.c rename to zfs/lib/libzpool/zfs_vfsops.c index 39c8ce4ef..06b4dee46 100644 --- a/zfs/lib/libdmu-ctl/zfs_vfsops.c +++ b/zfs/lib/libzpool/zfs_vfsops.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_vfsops.c 1.41 08/04/11 SMI" - #include #include #include @@ -477,8 +475,9 @@ zfs_register_callbacks(vfs_t *vfsp) dmu_objset_name(os, osname); if (error = dsl_prop_get_integer(osname, "nbmand", &nbmand, - NULL)) - return (error); + NULL)) { + return (error); + } } /* @@ -558,7 +557,6 @@ unregister: static int zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) { - uint_t readonly; int error; error = zfs_register_callbacks(zfsvfs->z_vfs); @@ -578,44 +576,22 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) * operations out since we closed the ZIL. */ if (mounting) { + boolean_t readonly; + /* * During replay we remove the read only flag to * allow replays to succeed. */ readonly = zfsvfs->z_vfs->vfs_flag & VFS_RDONLY; - if (readonly != 0) - zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY; - else - zfs_unlinked_drain(zfsvfs); + zfsvfs->z_vfs->vfs_flag &= ~VFS_RDONLY; /* * Parse and replay the intent log. - * - * Because of ziltest, this must be done after - * zfs_unlinked_drain(). (Further note: ziltest doesn't - * use readonly mounts, where zfs_unlinked_drain() isn't - * called.) This is because ziltest causes spa_sync() - * to think it's committed, but actually it is not, so - * the intent log contains many txg's worth of changes. - * - * In particular, if object N is in the unlinked set in - * the last txg to actually sync, then it could be - * actually freed in a later txg and then reallocated in - * a yet later txg. This would write a "create object - * N" record to the intent log. Normally, this would be - * fine because the spa_sync() would have written out - * the fact that object N is free, before we could write - * the "create object N" intent log record. - * - * But when we are in ziltest mode, we advance the "open - * txg" without actually spa_sync()-ing the changes to - * disk. So we would see that object N is still - * allocated and in the unlinked set, and there is an - * intent log record saying to allocate it. */ zil_replay(zfsvfs->z_os, zfsvfs, &zfsvfs->z_assign, - zfs_replay_vector); + zfs_replay_vector, zfs_unlinked_drain); + zfs_unlinked_drain(zfsvfs); zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */ } @@ -638,7 +614,7 @@ zfs_freezfsvfs(zfsvfs_t *zfsvfs) } static int -zfs_domount(vfs_t *vfsp, char *osname, cred_t *cr) +zfs_domount(vfs_t *vfsp, char *osname) { dev_t mount_dev; uint64_t recordsize, readonly; @@ -693,14 +669,13 @@ zfs_domount(vfs_t *vfsp, char *osname, cred_t *cr) if (error = dsl_prop_get_integer(osname, "readonly", &readonly, NULL)) goto out; + mode = DS_MODE_OWNER; if (readonly) - mode = DS_MODE_PRIMARY | DS_MODE_READONLY; - else - mode = DS_MODE_PRIMARY; + mode |= DS_MODE_READONLY; error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &zfsvfs->z_os); if (error == EROFS) { - mode = DS_MODE_PRIMARY | DS_MODE_READONLY; + mode = DS_MODE_OWNER | DS_MODE_READONLY; error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &zfsvfs->z_os); } @@ -708,7 +683,7 @@ zfs_domount(vfs_t *vfsp, char *osname, cred_t *cr) if (error) goto out; - if (error = zfs_init_fs(zfsvfs, &zp, cr)) + if (error = zfs_init_fs(zfsvfs, &zp)) goto out; /* The call to zfs_init_fs leaves the vnode held, release it here. */ @@ -720,6 +695,7 @@ zfs_domount(vfs_t *vfsp, char *osname, cred_t *cr) zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os); if (zfsvfs->z_use_fuids) { vfs_set_feature(vfsp, VFSFT_XVATTR); + vfs_set_feature(vfsp, VFSFT_SYSATTR_VIEWS); vfs_set_feature(vfsp, VFSFT_ACEMASKONACCESS); vfs_set_feature(vfsp, VFSFT_ACLONCREATE); } @@ -840,16 +816,19 @@ zfs_parse_bootfs(char *bpath, char *outpath) if (*bpath == 0 || *bpath == '/') return (EINVAL); + (void) strcpy(outpath, bpath); + slashp = strchr(bpath, '/'); /* if no '/', just return the pool name */ if (slashp == NULL) { - (void) strcpy(outpath, bpath); return (0); } - if (error = str_to_uint64(slashp+1, &objnum)) - return (error); + /* if not a number, just return the root dataset name */ + if (str_to_uint64(slashp+1, &objnum)) { + return (0); + } *slashp = '\0'; error = dsl_dsobj_to_dsname(bpath, objnum, outpath); @@ -867,6 +846,7 @@ zfs_mountroot(vfs_t *vfsp, enum whymountroot why) znode_t *zp = NULL; vnode_t *vp = NULL; char *zfs_bootfs; + char *zfs_devid; ASSERT(vfsp); @@ -886,40 +866,42 @@ zfs_mountroot(vfs_t *vfsp, enum whymountroot why) */ clkset(-1); - if ((zfs_bootfs = spa_get_bootfs()) == NULL) { - cmn_err(CE_NOTE, "\nspa_get_bootfs: can not get " - "bootfs name \n"); + if ((zfs_bootfs = spa_get_bootprop("zfs-bootfs")) == NULL) { + cmn_err(CE_NOTE, "spa_get_bootfs: can not get " + "bootfs name"); return (EINVAL); } - - if (error = spa_import_rootpool(rootfs.bo_name)) { - spa_free_bootfs(zfs_bootfs); - cmn_err(CE_NOTE, "\nspa_import_rootpool: error %d\n", + zfs_devid = spa_get_bootprop("diskdevid"); + error = spa_import_rootpool(rootfs.bo_name, zfs_devid); + if (zfs_devid) + spa_free_bootprop(zfs_devid); + if (error) { + spa_free_bootprop(zfs_bootfs); + cmn_err(CE_NOTE, "spa_import_rootpool: error %d", error); return (error); } - if (error = zfs_parse_bootfs(zfs_bootfs, rootfs.bo_name)) { - spa_free_bootfs(zfs_bootfs); - cmn_err(CE_NOTE, "\nzfs_parse_bootfs: error %d\n", + spa_free_bootprop(zfs_bootfs); + cmn_err(CE_NOTE, "zfs_parse_bootfs: error %d", error); return (error); } - spa_free_bootfs(zfs_bootfs); + spa_free_bootprop(zfs_bootfs); if (error = vfs_lock(vfsp)) return (error); - if (error = zfs_domount(vfsp, rootfs.bo_name, CRED())) { - cmn_err(CE_NOTE, "\nzfs_domount: error %d\n", error); + if (error = zfs_domount(vfsp, rootfs.bo_name)) { + cmn_err(CE_NOTE, "zfs_domount: error %d", error); goto out; } zfsvfs = (zfsvfs_t *)vfsp->vfs_data; ASSERT(zfsvfs); if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp)) { - cmn_err(CE_NOTE, "\nzfs_zget: error %d\n", error); + cmn_err(CE_NOTE, "zfs_zget: error %d", error); goto out; } @@ -930,10 +912,8 @@ zfs_mountroot(vfs_t *vfsp, enum whymountroot why) rootvp = vp; /* - * The zfs_zget call above returns with a hold on vp, we release - * it here. + * Leave rootvp held. The root file system is never unmounted. */ - VN_RELE(vp); vfs_add((struct vnode *)0, vfsp, (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0); @@ -1057,7 +1037,7 @@ zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr) goto out; } - error = zfs_domount(vfsp, osname, cr); + error = zfs_domount(vfsp, osname); out: pn_free(&spn); @@ -1313,7 +1293,7 @@ zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr) mutex_exit(&os->os->os_user_ptr_lock); /* - * Finally close the objset + * Finally release the objset */ dmu_objset_close(os); } @@ -1582,7 +1562,7 @@ zfs_set_version(const char *name, uint64_t newvers) if (newvers < ZPL_VERSION_INITIAL || newvers > ZPL_VERSION) return (EINVAL); - error = dmu_objset_open(name, DMU_OST_ZFS, DS_MODE_PRIMARY, &os); + error = dmu_objset_open(name, DMU_OST_ZFS, DS_MODE_OWNER, &os); if (error) return (error); @@ -1623,7 +1603,7 @@ int zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value) { const char *pname; - int error; + int error = ENOENT; /* * Look up the file system's value for the property. For the @@ -1634,7 +1614,8 @@ zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value) else pname = zfs_prop_to_name(prop); - error = zap_lookup(os, MASTER_NODE_OBJ, pname, 8, 1, value); + if (os != NULL) + error = zap_lookup(os, MASTER_NODE_OBJ, pname, 8, 1, value); if (error == ENOENT) { /* No value set, use the default value */ diff --git a/zfs/lib/libdmu-ctl/zfs_vnops.c b/zfs/lib/libzpool/zfs_vnops.c similarity index 97% rename from zfs/lib/libdmu-ctl/zfs_vnops.c rename to zfs/lib/libzpool/zfs_vnops.c index 3f36328de..8e0037e37 100644 --- a/zfs/lib/libdmu-ctl/zfs_vnops.c +++ b/zfs/lib/libzpool/zfs_vnops.c @@ -25,8 +25,6 @@ /* Portions Copyright 2007 Jeremy Teo */ -#pragma ident "@(#)zfs_vnops.c 1.73 08/04/27 SMI" - #include #include #include @@ -47,6 +45,8 @@ #include #include #include +#include +#include #include #include #include @@ -65,6 +65,7 @@ #include #include #include +#include #include "fs/fs_subr.h" #include #include @@ -169,23 +170,32 @@ static int zfs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct) { znode_t *zp = VTOZ(*vpp); + zfsvfs_t *zfsvfs = zp->z_zfsvfs; + + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); if ((flag & FWRITE) && (zp->z_phys->zp_flags & ZFS_APPENDONLY) && ((flag & FAPPEND) == 0)) { + ZFS_EXIT(zfsvfs); return (EPERM); } if (!zfs_has_ctldir(zp) && zp->z_zfsvfs->z_vscan && ZTOV(zp)->v_type == VREG && !(zp->z_phys->zp_flags & ZFS_AV_QUARANTINED) && - zp->z_phys->zp_size > 0) - if (fs_vscan(*vpp, cr, 0) != 0) + zp->z_phys->zp_size > 0) { + if (fs_vscan(*vpp, cr, 0) != 0) { + ZFS_EXIT(zfsvfs); return (EACCES); + } + } /* Keep a count of the synchronous opens in the znode */ if (flag & (FSYNC | FDSYNC)) atomic_inc_32(&zp->z_sync_cnt); + ZFS_EXIT(zfsvfs); return (0); } @@ -195,6 +205,10 @@ zfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr, caller_context_t *ct) { znode_t *zp = VTOZ(vp); + zfsvfs_t *zfsvfs = zp->z_zfsvfs; + + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); /* Decrement the synchronous opens in the znode */ if ((flag & (FSYNC | FDSYNC)) && (count == 1)) @@ -212,6 +226,7 @@ zfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr, zp->z_phys->zp_size > 0) VERIFY(fs_vscan(vp, cr, 1) == 0); + ZFS_EXIT(zfsvfs); return (0); } @@ -302,6 +317,31 @@ zfs_ioctl(vnode_t *vp, int com, intptr_t data, int flag, cred_t *cred, return (ENOTTY); } +/* + * Utility functions to map and unmap a single physical page. These + * are used to manage the mappable copies of ZFS file data, and therefore + * do not update ref/mod bits. + */ +caddr_t +zfs_map_page(page_t *pp, enum seg_rw rw) +{ + if (kpm_enable) + return (hat_kpm_mapin(pp, 0)); + ASSERT(rw == S_READ || rw == S_WRITE); + return (ppmapin(pp, PROT_READ | ((rw == S_WRITE) ? PROT_WRITE : 0), + (caddr_t)-1)); +} + +void +zfs_unmap_page(page_t *pp, caddr_t addr) +{ + if (kpm_enable) { + hat_kpm_mapout(pp, 0, addr); + } else { + ppmapout(addr); + } +} + /* * When a file is memory mapped, we must keep the IO data synchronized * between the DMU cache and the memory mapped pages. What this means: @@ -339,13 +379,13 @@ mappedwrite(vnode_t *vp, int nbytes, uio_t *uio, dmu_tx_t *tx) caddr_t va; rw_exit(&zp->z_map_lock); - va = ppmapin(pp, PROT_READ | PROT_WRITE, (caddr_t)-1L); + va = zfs_map_page(pp, S_WRITE); error = uiomove(va+off, bytes, UIO_WRITE, uio); if (error == 0) { dmu_write(zfsvfs->z_os, zp->z_id, woff, bytes, va+off, tx); } - ppmapout(va); + zfs_unmap_page(pp, va); page_unlock(pp); } else { error = dmu_write_uio(zfsvfs->z_os, zp->z_id, @@ -388,9 +428,9 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) if (pp = page_lookup(vp, start, SE_SHARED)) { caddr_t va; - va = ppmapin(pp, PROT_READ, (caddr_t)-1L); + va = zfs_map_page(pp, S_READ); error = uiomove(va + off, bytes, UIO_READ, uio); - ppmapout(va); + zfs_unmap_page(pp, va); page_unlock(pp); } else { error = dmu_read_uio(os, zp->z_id, uio, bytes); @@ -501,8 +541,12 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) error = mappedread(vp, nbytes, uio); else error = dmu_read_uio(os, zp->z_id, uio, nbytes); - if (error) + if (error) { + /* convert checksum errors into IO errors */ + if (error == ECKSUM) + error = EIO; break; + } n -= nbytes; } @@ -515,69 +559,6 @@ out: return (error); } -/* - * Fault in the pages of the first n bytes specified by the uio structure. - * 1 byte in each page is touched and the uio struct is unmodified. - * Any error will exit this routine as this is only a best - * attempt to get the pages resident. This is a copy of ufs_trans_touch(). - */ -static void -zfs_prefault_write(ssize_t n, struct uio *uio) -{ - struct iovec *iov; - ulong_t cnt, incr; - caddr_t p; - uint8_t tmp; - - iov = uio->uio_iov; - - while (n) { - cnt = MIN(iov->iov_len, n); - if (cnt == 0) { - /* empty iov entry */ - iov++; - continue; - } - n -= cnt; - /* - * touch each page in this segment. - */ - p = iov->iov_base; - while (cnt) { - switch (uio->uio_segflg) { - case UIO_USERSPACE: - case UIO_USERISPACE: - if (fuword8(p, &tmp)) - return; - break; - case UIO_SYSSPACE: - if (kcopy(p, &tmp, 1)) - return; - break; - } - incr = MIN(cnt, PAGESIZE); - p += incr; - cnt -= incr; - } - /* - * touch the last byte in case it straddles a page. - */ - p--; - switch (uio->uio_segflg) { - case UIO_USERSPACE: - case UIO_USERISPACE: - if (fuword8(p, &tmp)) - return; - break; - case UIO_SYSSPACE: - if (kcopy(p, &tmp, 1)) - return; - break; - } - iov++; - } -} - /* * Write the bytes to a file. * @@ -612,17 +593,9 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) ssize_t n, nbytes; rl_t *rl; int max_blksz = zfsvfs->z_max_blksz; - uint64_t pflags = zp->z_phys->zp_flags; + uint64_t pflags; int error; - /* - * If immutable or not appending then return EPERM - */ - if ((pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) || - ((pflags & ZFS_APPENDONLY) && !(ioflag & FAPPEND) && - (uio->uio_loffset < zp->z_phys->zp_size))) - return (EPERM); - /* * Fasttrack empty write */ @@ -635,13 +608,25 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zp); + + /* + * If immutable or not appending then return EPERM + */ + pflags = zp->z_phys->zp_flags; + if ((pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) || + ((pflags & ZFS_APPENDONLY) && !(ioflag & FAPPEND) && + (uio->uio_loffset < zp->z_phys->zp_size))) { + ZFS_EXIT(zfsvfs); + return (EPERM); + } + zilog = zfsvfs->z_log; /* * Pre-fault the pages to ensure slow (eg NFS) pages * don't hold up txg. */ - zfs_prefault_write(n, uio); + uio_prefaultpages(n, uio); /* * If in append mode, set the io offset pointer to eof. @@ -1125,15 +1110,24 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, vcexcl_t excl, int error; zfs_acl_t *aclp = NULL; zfs_fuid_info_t *fuidp = NULL; + ksid_t *ksid; + uid_t uid; + gid_t gid = crgetgid(cr); /* * If we have an ephemeral id, ACL, or XVATTR then * make sure file system is at proper version */ + ksid = crgetsid(cr, KSID_OWNER); + if (ksid) + uid = ksid_getid(ksid); + else + uid = crgetuid(cr); + if (zfsvfs->z_use_fuids == B_FALSE && (vsecp || (vap->va_mask & AT_XVATTR) || - IS_EPHEMERAL(crgetuid(cr)) || IS_EPHEMERAL(crgetgid(cr)))) + IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid))) return (EINVAL); ZFS_ENTER(zfsvfs); @@ -1219,8 +1213,8 @@ top: tx = dmu_tx_create(os); dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); - if ((aclp && aclp->z_has_fuids) || IS_EPHEMERAL(crgetuid(cr)) || - IS_EPHEMERAL(crgetgid(cr))) { + if ((aclp && aclp->z_has_fuids) || IS_EPHEMERAL(uid) || + IS_EPHEMERAL(gid)) { if (zfsvfs->z_fuid_obj == 0) { dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, @@ -1300,15 +1294,10 @@ top: */ if ((ZTOV(zp)->v_type == VREG) && (vap->va_mask & AT_SIZE) && (vap->va_size == 0)) { + /* we can't hold any locks when calling zfs_freesp() */ + zfs_dirent_unlock(dl); + dl = NULL; error = zfs_freesp(zp, 0, 0, mode, TRUE); - if (error == ERESTART && - zfsvfs->z_assign == TXG_NOWAIT) { - /* NB: we already did dmu_tx_wait() */ - zfs_dirent_unlock(dl); - VN_RELE(ZTOV(zp)); - goto top; - } - if (error == 0) { vnevent_create(ZTOV(zp), ct); } @@ -1375,7 +1364,7 @@ zfs_remove(vnode_t *dvp, char *name, cred_t *cr, caller_context_t *ct, zfs_dirlock_t *dl; dmu_tx_t *tx; boolean_t may_delete_now, delete_now = FALSE; - boolean_t unlinked; + boolean_t unlinked, toobig = FALSE; uint64_t txtype; pathname_t *realnmp = NULL; pathname_t realnm; @@ -1438,8 +1427,13 @@ top: tx = dmu_tx_create(zfsvfs->z_os); dmu_tx_hold_zap(tx, dzp->z_id, FALSE, name); dmu_tx_hold_bonus(tx, zp->z_id); - if (may_delete_now) - dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END); + if (may_delete_now) { + toobig = + zp->z_phys->zp_size > zp->z_blksz * DMU_MAX_DELETEBLKCNT; + /* if the file is too big, only hold_free a token amount */ + dmu_tx_hold_free(tx, zp->z_id, 0, + (toobig ? DMU_MAX_ACCESS : DMU_OBJECT_END)); + } /* are there any extended attributes? */ if ((xattr_obj = zp->z_phys->zp_xattr) != 0) { @@ -1483,7 +1477,7 @@ top: if (unlinked) { mutex_enter(&vp->v_lock); - delete_now = may_delete_now && + delete_now = may_delete_now && !toobig && vp->v_count == 1 && !vn_has_cached_data(vp) && zp->z_phys->zp_xattr == xattr_obj && zp->z_phys->zp_acl.z_acl_extern_obj == acl_obj; @@ -1529,7 +1523,7 @@ out: if (!delete_now) { VN_RELE(vp); } else if (xzp) { - /* this rele delayed to prevent nesting transactions */ + /* this rele is delayed to prevent nesting transactions */ VN_RELE(ZTOV(xzp)); } @@ -1572,6 +1566,9 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, zfs_acl_t *aclp = NULL; zfs_fuid_info_t *fuidp = NULL; int zf = ZNEW; + ksid_t *ksid; + uid_t uid; + gid_t gid = crgetgid(cr); ASSERT(vap->va_type == VDIR); @@ -1580,9 +1577,14 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, * make sure file system is at proper version */ + ksid = crgetsid(cr, KSID_OWNER); + if (ksid) + uid = ksid_getid(ksid); + else + uid = crgetuid(cr); if (zfsvfs->z_use_fuids == B_FALSE && - (vsecp || (vap->va_mask & AT_XVATTR) || IS_EPHEMERAL(crgetuid(cr))|| - IS_EPHEMERAL(crgetgid(cr)))) + (vsecp || (vap->va_mask & AT_XVATTR) || + IS_EPHEMERAL(uid) || IS_EPHEMERAL(gid))) return (EINVAL); ZFS_ENTER(zfsvfs); @@ -1641,8 +1643,8 @@ top: tx = dmu_tx_create(zfsvfs->z_os); dmu_tx_hold_zap(tx, dzp->z_id, TRUE, dirname); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); - if ((aclp && aclp->z_has_fuids) || IS_EPHEMERAL(crgetuid(cr)) || - IS_EPHEMERAL(crgetgid(cr))) { + if ((aclp && aclp->z_has_fuids) || IS_EPHEMERAL(uid) || + IS_EPHEMERAL(gid)) { if (zfsvfs->z_fuid_obj == 0) { dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, @@ -1936,12 +1938,12 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, eodp = (struct edirent *)odp; /* - * If this VFS supports system attributes; and we're looking at an - * extended attribute directory; and we care about normalization - * conflicts on this vfs; then we must check for normalization - * conflicts with the sysattr name space. + * If this VFS supports the system attribute view interface; and + * we're looking at an extended attribute directory; and we care + * about normalization conflicts on this vfs; then we must check + * for normalization conflicts with the sysattr name space. */ - check_sysattrs = vfs_has_feature(vp->v_vfsp, VFSFT_XVATTR) && + check_sysattrs = vfs_has_feature(vp->v_vfsp, VFSFT_SYSATTR_VIEWS) && (vp->v_flag & V_XATTRDIR) && zfsvfs->z_norm && (flags & V_RDDIR_ENTFLAGS); @@ -2447,10 +2449,8 @@ top: * block if there are locks present... this * should be addressed in openat(). */ - do { - err = zfs_freesp(zp, vap->va_size, 0, 0, FALSE); - /* NB: we already did dmu_tx_wait() if necessary */ - } while (err == ERESTART && zfsvfs->z_assign == TXG_NOWAIT); + /* XXX - would it be OK to generate a log record here? */ + err = zfs_freesp(zp, vap->va_size, 0, 0, FALSE); if (err) { ZFS_EXIT(zfsvfs); return (err); @@ -2721,6 +2721,7 @@ top: if (mask & AT_MTIME) ZFS_TIME_ENCODE(&vap->va_mtime, pzp->zp_mtime); + /* XXX - shouldn't this be done *before* the ATIME/MTIME checks? */ if (mask & AT_SIZE) zfs_time_stamper_locked(zp, CONTENT_MODIFIED, tx); else if (mask != 0) @@ -3136,6 +3137,9 @@ top: zfs_log_rename(zilog, tx, TX_RENAME | (flags & FIGNORECASE ? TX_CI : 0), sdzp, sdl->dl_name, tdzp, tdl->dl_name, szp); + + /* Update path information for the target vnode */ + vn_renamepath(tdvp, ZTOV(szp), tnm, strlen(tnm)); } } @@ -3599,10 +3603,10 @@ top: } if (zp->z_blksz <= PAGESIZE) { - caddr_t va = ppmapin(pp, PROT_READ, (caddr_t)-1); + caddr_t va = zfs_map_page(pp, S_READ); ASSERT3U(len, <=, PAGESIZE); dmu_write(zfsvfs->z_os, zp->z_id, off, len, va, tx); - ppmapout(va); + zfs_unmap_page(pp, va); } else { err = dmu_write_pages(zfsvfs->z_os, zp->z_id, off, len, pp, tx); } @@ -3885,12 +3889,15 @@ zfs_fillpage(vnode_t *vp, u_offset_t off, struct seg *seg, cur_pp = pp; for (total = io_off + io_len; io_off < total; io_off += PAGESIZE) { ASSERT3U(io_off, ==, cur_pp->p_offset); - va = ppmapin(cur_pp, PROT_READ | PROT_WRITE, (caddr_t)-1); + va = zfs_map_page(cur_pp, S_WRITE); err = dmu_read(os, oid, io_off, PAGESIZE, va); - ppmapout(va); + zfs_unmap_page(cur_pp, va); if (err) { /* On error, toss the entire kluster */ pvn_read_done(pp, B_ERROR); + /* convert checksum errors into IO errors */ + if (err == ECKSUM) + err = EIO; return (err); } cur_pp = cur_pp->p_next; @@ -4229,7 +4236,6 @@ zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zp); -top: if (cmd != F_FREESP) { ZFS_EXIT(zfsvfs); return (EINVAL); @@ -4248,10 +4254,7 @@ top: off = bfp->l_start; len = bfp->l_len; /* 0 means from off to end of file */ - do { - error = zfs_freesp(zp, off, len, flag, TRUE); - /* NB: we already did dmu_tx_wait() if necessary */ - } while (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT); + error = zfs_freesp(zp, off, len, flag, TRUE); ZFS_EXIT(zfsvfs); return (error); @@ -4353,7 +4356,7 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, case _PC_SATTR_ENABLED: case _PC_SATTR_EXISTS: - *valp = vfs_has_feature(vp->v_vfsp, VFSFT_XVATTR) && + *valp = vfs_has_feature(vp->v_vfsp, VFSFT_SYSATTR_VIEWS) && (vp->v_type == VREG || vp->v_type == VDIR); return (0); diff --git a/zfs/lib/libzpool/zfs_znode.c b/zfs/lib/libzpool/zfs_znode.c index 18ab8350f..25751ae5f 100644 --- a/zfs/lib/libzpool/zfs_znode.c +++ b/zfs/lib/libzpool/zfs_znode.c @@ -25,8 +25,6 @@ /* Portions Copyright 2007 Jeremy Teo */ -#pragma ident "@(#)zfs_znode.c 1.34 08/04/27 SMI" - #ifdef _KERNEL #include #include @@ -66,13 +64,30 @@ #include "zfs_prop.h" +/* + * Define ZNODE_STATS to turn on statistic gathering. By default, it is only + * turned on when DEBUG is also defined. + */ +#ifdef DEBUG +#define ZNODE_STATS +#endif /* DEBUG */ + +#ifdef ZNODE_STATS +#define ZNODE_STAT_ADD(stat) ((stat)++) +#else +#define ZNODE_STAT_ADD(stat) /* nothing */ +#endif /* ZNODE_STATS */ + +#define POINTER_IS_VALID(p) (!((uintptr_t)(p) & 0x3)) +#define POINTER_INVALIDATE(pp) (*(pp) = (void *)((uintptr_t)(*(pp)) | 0x1)) + /* * Functions needed for userland (ie: libzpool) are not put under * #ifdef_KERNEL; the rest of the functions have dependencies * (such as VFS logic) that will not compile easily in userland. */ #ifdef _KERNEL -struct kmem_cache *znode_cache = NULL; +static kmem_cache_t *znode_cache = NULL; /*ARGSUSED*/ static void @@ -87,12 +102,20 @@ znode_evict_error(dmu_buf_t *dbuf, void *user_ptr) /*ARGSUSED*/ static int -zfs_znode_cache_constructor(void *buf, void *cdrarg, int kmflags) +zfs_znode_cache_constructor(void *buf, void *arg, int kmflags) { znode_t *zp = buf; - zp->z_vnode = vn_alloc(KM_SLEEP); - zp->z_vnode->v_data = (caddr_t)zp; + ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); + + zp->z_vnode = vn_alloc(kmflags); + if (zp->z_vnode == NULL) { + return (-1); + } + ZTOV(zp)->v_data = zp; + + list_link_init(&zp->z_link_node); + mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL); rw_init(&zp->z_map_lock, NULL, RW_DEFAULT, NULL); rw_init(&zp->z_parent_lock, NULL, RW_DEFAULT, NULL); @@ -104,17 +127,20 @@ zfs_znode_cache_constructor(void *buf, void *cdrarg, int kmflags) sizeof (rl_t), offsetof(rl_t, r_node)); zp->z_dbuf = NULL; - zp->z_dirlocks = 0; + zp->z_dirlocks = NULL; return (0); } /*ARGSUSED*/ static void -zfs_znode_cache_destructor(void *buf, void *cdarg) +zfs_znode_cache_destructor(void *buf, void *arg) { znode_t *zp = buf; - ASSERT(zp->z_dirlocks == 0); + ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); + ASSERT(ZTOV(zp)->v_data == zp); + vn_free(ZTOV(zp)); + ASSERT(!list_link_active(&zp->z_link_node)); mutex_destroy(&zp->z_lock); rw_destroy(&zp->z_map_lock); rw_destroy(&zp->z_parent_lock); @@ -124,8 +150,161 @@ zfs_znode_cache_destructor(void *buf, void *cdarg) mutex_destroy(&zp->z_range_lock); ASSERT(zp->z_dbuf == NULL); - ASSERT(ZTOV(zp)->v_count == 0); - vn_free(ZTOV(zp)); + ASSERT(zp->z_dirlocks == NULL); +} + +#ifdef ZNODE_STATS +static struct { + uint64_t zms_zfsvfs_invalid; + uint64_t zms_zfsvfs_unmounted; + uint64_t zms_zfsvfs_recheck_invalid; + uint64_t zms_obj_held; + uint64_t zms_vnode_locked; + uint64_t zms_not_only_dnlc; +} znode_move_stats; +#endif /* ZNODE_STATS */ + +static void +zfs_znode_move_impl(znode_t *ozp, znode_t *nzp) +{ + vnode_t *vp; + + /* Copy fields. */ + nzp->z_zfsvfs = ozp->z_zfsvfs; + + /* Swap vnodes. */ + vp = nzp->z_vnode; + nzp->z_vnode = ozp->z_vnode; + ozp->z_vnode = vp; /* let destructor free the overwritten vnode */ + ZTOV(ozp)->v_data = ozp; + ZTOV(nzp)->v_data = nzp; + + nzp->z_id = ozp->z_id; + ASSERT(ozp->z_dirlocks == NULL); /* znode not in use */ + ASSERT(avl_numnodes(&ozp->z_range_avl) == 0); + nzp->z_unlinked = ozp->z_unlinked; + nzp->z_atime_dirty = ozp->z_atime_dirty; + nzp->z_zn_prefetch = ozp->z_zn_prefetch; + nzp->z_blksz = ozp->z_blksz; + nzp->z_seq = ozp->z_seq; + nzp->z_mapcnt = ozp->z_mapcnt; + nzp->z_last_itx = ozp->z_last_itx; + nzp->z_gen = ozp->z_gen; + nzp->z_sync_cnt = ozp->z_sync_cnt; + nzp->z_phys = ozp->z_phys; + nzp->z_dbuf = ozp->z_dbuf; + + /* Update back pointers. */ + (void) dmu_buf_update_user(nzp->z_dbuf, ozp, nzp, &nzp->z_phys, + znode_evict_error); + + /* + * Invalidate the original znode by clearing fields that provide a + * pointer back to the znode. Set the low bit of the vfs pointer to + * ensure that zfs_znode_move() recognizes the znode as invalid in any + * subsequent callback. + */ + ozp->z_dbuf = NULL; + POINTER_INVALIDATE(&ozp->z_zfsvfs); +} + +/* + * Wrapper function for ZFS_ENTER that returns 0 if successful and otherwise + * returns a non-zero error code. + */ +static int +zfs_enter(zfsvfs_t *zfsvfs) +{ + ZFS_ENTER(zfsvfs); + return (0); +} + +/*ARGSUSED*/ +static kmem_cbrc_t +zfs_znode_move(void *buf, void *newbuf, size_t size, void *arg) +{ + znode_t *ozp = buf, *nzp = newbuf; + zfsvfs_t *zfsvfs; + vnode_t *vp; + + /* + * The znode is on the file system's list of known znodes if the vfs + * pointer is valid. We set the low bit of the vfs pointer when freeing + * the znode to invalidate it, and the memory patterns written by kmem + * (baddcafe and deadbeef) set at least one of the two low bits. A newly + * created znode sets the vfs pointer last of all to indicate that the + * znode is known and in a valid state to be moved by this function. + */ + zfsvfs = ozp->z_zfsvfs; + if (!POINTER_IS_VALID(zfsvfs)) { + ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_invalid); + return (KMEM_CBRC_DONT_KNOW); + } + + /* + * Ensure that the filesystem is not unmounted during the move. + */ + if (zfs_enter(zfsvfs) != 0) { /* ZFS_ENTER */ + ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_unmounted); + return (KMEM_CBRC_DONT_KNOW); + } + + mutex_enter(&zfsvfs->z_znodes_lock); + /* + * Recheck the vfs pointer in case the znode was removed just before + * acquiring the lock. + */ + if (zfsvfs != ozp->z_zfsvfs) { + mutex_exit(&zfsvfs->z_znodes_lock); + ZFS_EXIT(zfsvfs); + ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck_invalid); + return (KMEM_CBRC_DONT_KNOW); + } + + /* + * At this point we know that as long as we hold z_znodes_lock, the + * znode cannot be freed and fields within the znode can be safely + * accessed. Now, prevent a race with zfs_zget(). + */ + if (ZFS_OBJ_HOLD_TRYENTER(zfsvfs, ozp->z_id) == 0) { + mutex_exit(&zfsvfs->z_znodes_lock); + ZFS_EXIT(zfsvfs); + ZNODE_STAT_ADD(znode_move_stats.zms_obj_held); + return (KMEM_CBRC_LATER); + } + + vp = ZTOV(ozp); + if (mutex_tryenter(&vp->v_lock) == 0) { + ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); + mutex_exit(&zfsvfs->z_znodes_lock); + ZFS_EXIT(zfsvfs); + ZNODE_STAT_ADD(znode_move_stats.zms_vnode_locked); + return (KMEM_CBRC_LATER); + } + + /* Only move znodes that are referenced _only_ by the DNLC. */ + if (vp->v_count != 1 || !vn_in_dnlc(vp)) { + mutex_exit(&vp->v_lock); + ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); + mutex_exit(&zfsvfs->z_znodes_lock); + ZFS_EXIT(zfsvfs); + ZNODE_STAT_ADD(znode_move_stats.zms_not_only_dnlc); + return (KMEM_CBRC_LATER); + } + + /* + * The znode is known and in a valid state to move. We're holding the + * locks needed to execute the critical section. + */ + zfs_znode_move_impl(ozp, nzp); + mutex_exit(&vp->v_lock); + ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); + + list_link_replace(&ozp->z_link_node, &nzp->z_link_node); + mutex_exit(&zfsvfs->z_znodes_lock); + ZFS_EXIT(zfsvfs); + + return (KMEM_CBRC_YES); } void @@ -138,6 +317,7 @@ zfs_znode_init(void) znode_cache = kmem_cache_create("zfs_znode_cache", sizeof (znode_t), 0, zfs_znode_cache_constructor, zfs_znode_cache_destructor, NULL, NULL, NULL, 0); + kmem_cache_set_move(znode_cache, zfs_znode_move); } void @@ -243,45 +423,17 @@ zfs_create_op_tables() * incore "master" object. Verify version compatibility. */ int -zfs_init_fs(zfsvfs_t *zfsvfs, znode_t **zpp, cred_t *cr) +zfs_init_fs(zfsvfs_t *zfsvfs, znode_t **zpp) { extern int zfsfstype; objset_t *os = zfsvfs->z_os; int i, error; - dmu_object_info_t doi; uint64_t fsid_guid; uint64_t zval; *zpp = NULL; - /* - * XXX - hack to auto-create the pool root filesystem at - * the first attempted mount. - */ - if (dmu_object_info(os, MASTER_NODE_OBJ, &doi) == ENOENT) { - dmu_tx_t *tx = dmu_tx_create(os); - uint64_t zpl_version; - nvlist_t *zprops; - - dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, NULL); /* master */ - dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, NULL); /* del queue */ - dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); /* root node */ - error = dmu_tx_assign(tx, TXG_WAIT); - ASSERT3U(error, ==, 0); - if (spa_version(dmu_objset_spa(os)) >= SPA_VERSION_FUID) - zpl_version = ZPL_VERSION; - else - zpl_version = ZPL_VERSION_FUID - 1; - - VERIFY(nvlist_alloc(&zprops, NV_UNIQUE_NAME, KM_SLEEP) == 0); - VERIFY(nvlist_add_uint64(zprops, - zfs_prop_to_name(ZFS_PROP_VERSION), zpl_version) == 0); - zfs_create_fs(os, cr, zprops, tx); - nvlist_free(zprops); - dmu_tx_commit(tx); - } - error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zfsvfs->z_version); if (error) { return (error); @@ -419,12 +571,12 @@ zfs_cmpldev(uint64_t dev) } static void -zfs_znode_dmu_init(znode_t *zp, dmu_buf_t *db) +zfs_znode_dmu_init(zfsvfs_t *zfsvfs, znode_t *zp, dmu_buf_t *db) { znode_t *nzp; - zfsvfs_t *zfsvfs = zp->z_zfsvfs; - ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zp))); + ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs) || (zfsvfs == zp->z_zfsvfs)); + ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id))); mutex_enter(&zp->z_lock); @@ -437,7 +589,7 @@ zfs_znode_dmu_init(znode_t *zp, dmu_buf_t *db) * concurrent zgets on this object. */ if (nzp != NULL) - panic("existing znode %p for dbuf %p", nzp, db); + panic("existing znode %p for dbuf %p", (void *)nzp, (void *)db); /* * Slap on VROOT if we are the root znode @@ -453,7 +605,8 @@ void zfs_znode_dmu_fini(znode_t *zp) { dmu_buf_t *db = zp->z_dbuf; - ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zp)) || zp->z_unlinked || + ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zp->z_zfsvfs, zp->z_id)) || + zp->z_unlinked || RW_WRITE_HELD(&zp->z_zfsvfs->z_teardown_inactive_lock)); ASSERT(zp->z_dbuf != NULL); zp->z_dbuf = NULL; @@ -478,9 +631,13 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz) ASSERT(zp->z_dirlocks == NULL); ASSERT(zp->z_dbuf == NULL); + ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); + /* + * Defer setting z_zfsvfs until the znode is ready to be a candidate for + * the zfs_znode_move() callback. + */ zp->z_phys = NULL; - zp->z_zfsvfs = zfsvfs; zp->z_unlinked = 0; zp->z_atime_dirty = 0; zp->z_mapcnt = 0; @@ -493,14 +650,10 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz) vp = ZTOV(zp); vn_reinit(vp); - zfs_znode_dmu_init(zp, db); + zfs_znode_dmu_init(zfsvfs, zp, db); zp->z_gen = zp->z_phys->zp_gen; - mutex_enter(&zfsvfs->z_znodes_lock); - list_insert_tail(&zfsvfs->z_all_znodes, zp); - mutex_exit(&zfsvfs->z_znodes_lock); - vp->v_vfsp = zfsvfs->z_parent->z_vfs; vp->v_type = IFTOVT((mode_t)zp->z_phys->zp_mode); @@ -535,6 +688,16 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz) break; } + mutex_enter(&zfsvfs->z_znodes_lock); + list_insert_tail(&zfsvfs->z_all_znodes, zp); + membar_producer(); + /* + * Everything else must be valid before assigning z_zfsvfs makes the + * znode eligible for zfs_znode_move(). + */ + zp->z_zfsvfs = zfsvfs; + mutex_exit(&zfsvfs->z_znodes_lock); + VFS_HOLD(zfsvfs->z_vfs); return (zp); } @@ -675,7 +838,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, pzp->zp_mode = MAKEIMODE(vap->va_type, vap->va_mode); if (!(flag & IS_ROOT_NODE)) { - ZFS_OBJ_HOLD_ENTER(zfsvfs, obj) + ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); *zpp = zfs_znode_alloc(zfsvfs, db, 0); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); } else { @@ -843,7 +1006,7 @@ zfs_rezget(znode_t *zp) return (EIO); } - zfs_znode_dmu_init(zp, db); + zfs_znode_dmu_init(zfsvfs, zp, db); zp->z_unlinked = (zp->z_phys->zp_links == 0); zp->z_blksz = doi.doi_data_block_size; @@ -856,14 +1019,14 @@ void zfs_znode_delete(znode_t *zp, dmu_tx_t *tx) { zfsvfs_t *zfsvfs = zp->z_zfsvfs; + objset_t *os = zfsvfs->z_os; uint64_t obj = zp->z_id; + uint64_t acl_obj = zp->z_phys->zp_acl.z_acl_extern_obj; ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); - if (zp->z_phys->zp_acl.z_acl_extern_obj) { - VERIFY(0 == dmu_object_free(zfsvfs->z_os, - zp->z_phys->zp_acl.z_acl_extern_obj, tx)); - } - VERIFY(0 == dmu_object_free(zfsvfs->z_os, obj, tx)); + if (acl_obj) + VERIFY(0 == dmu_object_free(os, acl_obj, tx)); + VERIFY(0 == dmu_object_free(os, obj, tx)); zfs_znode_dmu_fini(zp); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); zfs_znode_free(zp); @@ -928,7 +1091,10 @@ zfs_znode_free(znode_t *zp) vn_invalid(ZTOV(zp)); + ASSERT(ZTOV(zp)->v_count == 0); + mutex_enter(&zfsvfs->z_znodes_lock); + POINTER_INVALIDATE(&zp->z_zfsvfs); list_remove(&zfsvfs->z_all_znodes, zp); mutex_exit(&zfsvfs->z_znodes_lock); @@ -1040,137 +1206,177 @@ zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, } /* - * Free space in a file. + * Increase the file length * * IN: zp - znode of file to free data in. - * off - start of section to free. - * len - length of section to free (0 => to EOF). - * flag - current file open mode flags. + * end - new end-of-file * * RETURN: 0 if success * error code if failure */ -int -zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) +static int +zfs_extend(znode_t *zp, uint64_t end) { - vnode_t *vp = ZTOV(zp); - dmu_tx_t *tx; zfsvfs_t *zfsvfs = zp->z_zfsvfs; - zilog_t *zilog = zfsvfs->z_log; + dmu_tx_t *tx; rl_t *rl; - uint64_t end = off + len; - uint64_t size, new_blksz; - uint64_t pflags = zp->z_phys->zp_flags; + uint64_t newblksz; int error; - if ((pflags & (ZFS_IMMUTABLE|ZFS_READONLY)) || - off < zp->z_phys->zp_size && (pflags & ZFS_APPENDONLY)) - return (EPERM); - - if (ZTOV(zp)->v_type == VFIFO) - return (0); - /* - * If we will change zp_size then lock the whole file, - * otherwise just lock the range being freed. + * We will change zp_size, lock the whole file. */ - if (len == 0 || off + len > zp->z_phys->zp_size) { - rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); - } else { - rl = zfs_range_lock(zp, off, len, RL_WRITER); - /* recheck, in case zp_size changed */ - if (off + len > zp->z_phys->zp_size) { - /* lost race: file size changed, lock whole file */ - zfs_range_unlock(rl); - rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); - } - } + rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); /* * Nothing to do if file already at desired length. */ - size = zp->z_phys->zp_size; - if (len == 0 && size == off && off != 0) { + if (end <= zp->z_phys->zp_size) { zfs_range_unlock(rl); return (0); } - - /* - * Check for any locks in the region to be freed. - */ - if (MANDLOCK(vp, (mode_t)zp->z_phys->zp_mode)) { - uint64_t start = off; - uint64_t extent = len; - - if (off > size) { - start = size; - extent += off - size; - } else if (len == 0) { - extent = size - off; - } - if (error = chklock(vp, FWRITE, start, extent, flag, NULL)) { - zfs_range_unlock(rl); - return (error); - } - } - +top: tx = dmu_tx_create(zfsvfs->z_os); dmu_tx_hold_bonus(tx, zp->z_id); - new_blksz = 0; - if (end > size && + if (end > zp->z_blksz && (!ISP2(zp->z_blksz) || zp->z_blksz < zfsvfs->z_max_blksz)) { /* * We are growing the file past the current block size. */ if (zp->z_blksz > zp->z_zfsvfs->z_max_blksz) { ASSERT(!ISP2(zp->z_blksz)); - new_blksz = MIN(end, SPA_MAXBLOCKSIZE); + newblksz = MIN(end, SPA_MAXBLOCKSIZE); } else { - new_blksz = MIN(end, zp->z_zfsvfs->z_max_blksz); + newblksz = MIN(end, zp->z_zfsvfs->z_max_blksz); } - dmu_tx_hold_write(tx, zp->z_id, 0, MIN(end, new_blksz)); - } else if (off < size) { - /* - * If len == 0, we are truncating the file. - */ - dmu_tx_hold_free(tx, zp->z_id, off, len ? len : DMU_OBJECT_END); + dmu_tx_hold_write(tx, zp->z_id, 0, newblksz); + } else { + newblksz = 0; } error = dmu_tx_assign(tx, zfsvfs->z_assign); if (error) { - if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) + if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { dmu_tx_wait(tx); + dmu_tx_abort(tx); + goto top; + } dmu_tx_abort(tx); zfs_range_unlock(rl); return (error); } + dmu_buf_will_dirty(zp->z_dbuf, tx); - if (new_blksz) - zfs_grow_blocksize(zp, new_blksz, tx); + if (newblksz) + zfs_grow_blocksize(zp, newblksz, tx); - if (end > size || len == 0) - zp->z_phys->zp_size = end; - - if (off < size) { - objset_t *os = zfsvfs->z_os; - uint64_t rlen = len; - - if (len == 0) - rlen = -1; - else if (end > size) - rlen = size - off; - VERIFY(0 == dmu_free_range(os, zp->z_id, off, rlen, tx)); - } - - if (log) { - zfs_time_stamper(zp, CONTENT_MODIFIED, tx); - zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len); - } + zp->z_phys->zp_size = end; zfs_range_unlock(rl); dmu_tx_commit(tx); + return (0); +} + +/* + * Free space in a file. + * + * IN: zp - znode of file to free data in. + * off - start of section to free. + * len - length of section to free. + * + * RETURN: 0 if success + * error code if failure + */ +static int +zfs_free_range(znode_t *zp, uint64_t off, uint64_t len) +{ + zfsvfs_t *zfsvfs = zp->z_zfsvfs; + rl_t *rl; + int error; + + /* + * Lock the range being freed. + */ + rl = zfs_range_lock(zp, off, len, RL_WRITER); + + /* + * Nothing to do if file already at desired length. + */ + if (off >= zp->z_phys->zp_size) { + zfs_range_unlock(rl); + return (0); + } + + if (off + len > zp->z_phys->zp_size) + len = zp->z_phys->zp_size - off; + + error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, off, len); + + zfs_range_unlock(rl); + + return (error); +} + +/* + * Truncate a file + * + * IN: zp - znode of file to free data in. + * end - new end-of-file. + * + * RETURN: 0 if success + * error code if failure + */ +static int +zfs_trunc(znode_t *zp, uint64_t end) +{ + zfsvfs_t *zfsvfs = zp->z_zfsvfs; + vnode_t *vp = ZTOV(zp); + dmu_tx_t *tx; + rl_t *rl; + int error; + + /* + * We will change zp_size, lock the whole file. + */ + rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); + + /* + * Nothing to do if file already at desired length. + */ + if (end >= zp->z_phys->zp_size) { + zfs_range_unlock(rl); + return (0); + } + + error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, end, -1); + if (error) { + zfs_range_unlock(rl); + return (error); + } +top: + tx = dmu_tx_create(zfsvfs->z_os); + dmu_tx_hold_bonus(tx, zp->z_id); + error = dmu_tx_assign(tx, zfsvfs->z_assign); + if (error) { + if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { + dmu_tx_wait(tx); + dmu_tx_abort(tx); + goto top; + } + dmu_tx_abort(tx); + zfs_range_unlock(rl); + return (error); + } + dmu_buf_will_dirty(zp->z_dbuf, tx); + + zp->z_phys->zp_size = end; + + dmu_tx_commit(tx); + + zfs_range_unlock(rl); + /* * Clear any mapped pages in the truncated region. This has to * happen outside of the transaction to avoid the possibility of @@ -1178,10 +1384,10 @@ zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) * about to invalidate. */ rw_enter(&zp->z_map_lock, RW_WRITER); - if (off < size && vn_has_cached_data(vp)) { + if (vn_has_cached_data(vp)) { page_t *pp; - uint64_t start = off & PAGEMASK; - int poff = off & PAGEOFFSET; + uint64_t start = end & PAGEMASK; + int poff = end & PAGEOFFSET; if (poff != 0 && (pp = page_lookup(vp, start, SE_SHARED))) { /* @@ -1200,12 +1406,79 @@ zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) return (0); } +/* + * Free space in a file + * + * IN: zp - znode of file to free data in. + * off - start of range + * len - end of range (0 => EOF) + * flag - current file open mode flags. + * log - TRUE if this action should be logged + * + * RETURN: 0 if success + * error code if failure + */ +int +zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) +{ + vnode_t *vp = ZTOV(zp); + dmu_tx_t *tx; + zfsvfs_t *zfsvfs = zp->z_zfsvfs; + zilog_t *zilog = zfsvfs->z_log; + int error; + + if (off > zp->z_phys->zp_size) { + error = zfs_extend(zp, off+len); + if (error == 0 && log) + goto log; + else + return (error); + } + + /* + * Check for any locks in the region to be freed. + */ + if (MANDLOCK(vp, (mode_t)zp->z_phys->zp_mode)) { + uint64_t length = (len ? len : zp->z_phys->zp_size - off); + if (error = chklock(vp, FWRITE, off, length, flag, NULL)) + return (error); + } + + if (len == 0) { + error = zfs_trunc(zp, off); + } else { + if ((error = zfs_free_range(zp, off, len)) == 0 && + off + len > zp->z_phys->zp_size) + error = zfs_extend(zp, off+len); + } + if (error || !log) + return (error); +log: + tx = dmu_tx_create(zfsvfs->z_os); + dmu_tx_hold_bonus(tx, zp->z_id); + error = dmu_tx_assign(tx, zfsvfs->z_assign); + if (error) { + if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { + dmu_tx_wait(tx); + dmu_tx_abort(tx); + goto log; + } + dmu_tx_abort(tx); + return (error); + } + + zfs_time_stamper(zp, CONTENT_MODIFIED, tx); + zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len); + + dmu_tx_commit(tx); + return (0); +} + void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) { zfsvfs_t zfsvfs; - uint64_t moid, doid; - uint64_t version = 0; + uint64_t moid, doid, version; uint64_t sense = ZFS_CASE_SENSITIVE; uint64_t norm = 0; nvpair_t *elem; @@ -1230,6 +1503,12 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) /* * Set starting attributes. */ + if (spa_version(dmu_objset_spa(os)) >= SPA_VERSION_FUID) + version = ZPL_VERSION; + else + version = ZPL_VERSION_FUID - 1; + error = zap_update(os, moid, ZPL_VERSION_STR, + 8, 1, &version, tx); elem = NULL; while ((elem = nvlist_next_nvpair(zplprops, elem)) != NULL) { /* For the moment we expect all zpl props to be uint64_ts */ @@ -1273,7 +1552,6 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) vattr.va_gid = crgetgid(cr); rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP); - rootzp->z_zfsvfs = &zfsvfs; rootzp->z_unlinked = 0; rootzp->z_atime_dirty = 0; @@ -1300,10 +1578,14 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) list_create(&zfsvfs.z_all_znodes, sizeof (znode_t), offsetof(znode_t, z_link_node)); + ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs)); + rootzp->z_zfsvfs = &zfsvfs; zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, 0, NULL, NULL); ASSERT3P(zp, ==, rootzp); + ASSERT(!vn_in_dnlc(ZTOV(rootzp))); /* not valid to move */ error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx); ASSERT(error == 0); + POINTER_INVALIDATE(&rootzp->z_zfsvfs); ZTOV(rootzp)->v_count = 0; dmu_buf_rele(rootzp->z_dbuf, NULL); diff --git a/zfs/lib/libzpool/zil.c b/zfs/lib/libzpool/zil.c index 4f9325dbb..95101882b 100644 --- a/zfs/lib/libzpool/zil.c +++ b/zfs/lib/libzpool/zil.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zil.c 1.34 08/02/22 SMI" - #include #include #include @@ -167,7 +165,11 @@ zil_read_log_block(zilog_t *zilog, const blkptr_t *bp, arc_buf_t **abufpp) *abufpp = NULL; - error = arc_read(NULL, zilog->zl_spa, &blk, byteswap_uint64_array, + /* + * We shouldn't be doing any scrubbing while we're doing log + * replay, it's OK to not lock. + */ + error = arc_read_nolock(NULL, zilog->zl_spa, &blk, arc_getbuf_func, abufpp, ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | ZIO_FLAG_SCRUB, &aflags, &zb); @@ -178,17 +180,20 @@ zil_read_log_block(zilog_t *zilog, const blkptr_t *bp, arc_buf_t **abufpp) zio_cksum_t cksum = bp->blk_cksum; /* + * Validate the checksummed log block. + * * Sequence numbers should be... sequential. The checksum * verifier for the next block should be bp's checksum plus 1. + * + * Also check the log chain linkage and size used. */ cksum.zc_word[ZIL_ZC_SEQ]++; - if (bcmp(&cksum, &ztp->zit_next_blk.blk_cksum, sizeof (cksum))) - error = ESTALE; - else if (BP_IS_HOLE(&ztp->zit_next_blk)) - error = ENOENT; - else if (ztp->zit_nused > (blksz - sizeof (zil_trailer_t))) - error = EOVERFLOW; + if (bcmp(&cksum, &ztp->zit_next_blk.blk_cksum, + sizeof (cksum)) || BP_IS_HOLE(&ztp->zit_next_blk) || + (ztp->zit_nused > (blksz - sizeof (zil_trailer_t)))) { + error = ECKSUM; + } if (error) { VERIFY(arc_buf_remove_ref(*abufpp, abufpp) == 1); @@ -283,7 +288,8 @@ zil_claim_log_block(zilog_t *zilog, blkptr_t *bp, void *tx, uint64_t first_txg) */ if (bp->blk_birth >= first_txg && zil_dva_tree_add(&zilog->zl_dva_tree, BP_IDENTITY(bp)) == 0) { - err = zio_wait(zio_claim(NULL, spa, first_txg, bp, NULL, NULL)); + err = zio_wait(zio_claim(NULL, spa, first_txg, bp, NULL, NULL, + ZIO_FLAG_MUSTSUCCEED)); ASSERT(err == 0); } } @@ -499,9 +505,9 @@ zil_claim(char *osname, void *txarg) objset_t *os; int error; - error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_STANDARD, &os); + error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os); if (error) { - cmn_err(CE_WARN, "can't process intent log for %s", osname); + cmn_err(CE_WARN, "can't open objset for %s", osname); return (0); } @@ -528,6 +534,83 @@ zil_claim(char *osname, void *txarg) return (0); } +/* + * Check the log by walking the log chain. + * Checksum errors are ok as they indicate the end of the chain. + * Any other error (no device or read failure) returns an error. + */ +/* ARGSUSED */ +int +zil_check_log_chain(char *osname, void *txarg) +{ + zilog_t *zilog; + zil_header_t *zh; + blkptr_t blk; + arc_buf_t *abuf; + objset_t *os; + char *lrbuf; + zil_trailer_t *ztp; + int error; + + error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os); + if (error) { + cmn_err(CE_WARN, "can't open objset for %s", osname); + return (0); + } + + zilog = dmu_objset_zil(os); + zh = zil_header_in_syncing_context(zilog); + blk = zh->zh_log; + if (BP_IS_HOLE(&blk)) { + dmu_objset_close(os); + return (0); /* no chain */ + } + + for (;;) { + error = zil_read_log_block(zilog, &blk, &abuf); + if (error) + break; + lrbuf = abuf->b_data; + ztp = (zil_trailer_t *)(lrbuf + BP_GET_LSIZE(&blk)) - 1; + blk = ztp->zit_next_blk; + VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1); + } + dmu_objset_close(os); + if (error == ECKSUM) + return (0); /* normal end of chain */ + return (error); +} + +/* + * Clear a log chain + */ +/* ARGSUSED */ +int +zil_clear_log_chain(char *osname, void *txarg) +{ + zilog_t *zilog; + zil_header_t *zh; + objset_t *os; + dmu_tx_t *tx; + int error; + + error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os); + if (error) { + cmn_err(CE_WARN, "can't open objset for %s", osname); + return (0); + } + + zilog = dmu_objset_zil(os); + tx = dmu_tx_create(zilog->zl_os); + (void) dmu_tx_assign(tx, TXG_WAIT); + zh = zil_header_in_syncing_context(zilog); + BP_ZERO(&zh->zh_log); + dsl_dataset_dirty(dmu_objset_ds(os), tx); + dmu_tx_commit(tx); + dmu_objset_close(os); + return (0); +} + static int zil_vdev_compare(const void *x1, const void *x2) { @@ -591,10 +674,9 @@ zil_flush_vdevs(zilog_t *zilog) if (avl_numnodes(t) == 0) return; - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); - zio = zio_root(spa, NULL, NULL, - ZIO_FLAG_CONFIG_HELD | ZIO_FLAG_CANFAIL); + zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL); while ((zv = avl_destroy_nodes(t, &cookie)) != NULL) { vdev_t *vd = vdev_lookup_top(spa, zv->zv_vdev); @@ -609,7 +691,7 @@ zil_flush_vdevs(zilog_t *zilog) */ (void) zio_wait(zio); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_STATE, FTAG); } /* @@ -621,6 +703,15 @@ zil_lwb_write_done(zio_t *zio) lwb_t *lwb = zio->io_private; zilog_t *zilog = lwb->lwb_zilog; + ASSERT(BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_OFF); + ASSERT(BP_GET_CHECKSUM(zio->io_bp) == ZIO_CHECKSUM_ZILOG); + ASSERT(BP_GET_TYPE(zio->io_bp) == DMU_OT_INTENT_LOG); + ASSERT(BP_GET_LEVEL(zio->io_bp) == 0); + ASSERT(BP_GET_BYTEORDER(zio->io_bp) == ZFS_HOST_BYTEORDER); + ASSERT(!BP_IS_GANG(zio->io_bp)); + ASSERT(!BP_IS_HOLE(zio->io_bp)); + ASSERT(zio->io_bp->blk_fill == 0); + /* * Now that we've written this log block, we have a stable pointer * to the next block in the chain, so it's OK to let the txg in @@ -638,9 +729,6 @@ zil_lwb_write_done(zio_t *zio) /* * Initialize the io for a log block. - * - * Note, we should not initialize the IO until we are about - * to use it, since zio_rewrite() does a spa_config_enter(). */ static void zil_lwb_write_init(zilog_t *zilog, lwb_t *lwb) @@ -658,7 +746,7 @@ zil_lwb_write_init(zilog_t *zilog, lwb_t *lwb) } if (lwb->lwb_zio == NULL) { lwb->lwb_zio = zio_rewrite(zilog->zl_root_zio, zilog->zl_spa, - ZIO_CHECKSUM_ZILOG, 0, &lwb->lwb_blk, lwb->lwb_buf, + 0, &lwb->lwb_blk, lwb->lwb_buf, lwb->lwb_sz, zil_lwb_write_done, lwb, ZIO_PRIORITY_LOG_WRITE, ZIO_FLAG_CANFAIL, &zb); } @@ -951,7 +1039,7 @@ zil_clean(zilog_t *zilog) mutex_exit(&zilog->zl_lock); } -void +static void zil_commit_writer(zilog_t *zilog, uint64_t seq, uint64_t foid) { uint64_t txg; @@ -961,7 +1049,7 @@ zil_commit_writer(zilog_t *zilog, uint64_t seq, uint64_t foid) spa_t *spa; zilog->zl_writer = B_TRUE; - zilog->zl_root_zio = NULL; + ASSERT(zilog->zl_root_zio == NULL); spa = zilog->zl_spa; if (zilog->zl_suspend) { @@ -1066,6 +1154,7 @@ zil_commit_writer(zilog_t *zilog, uint64_t seq, uint64_t foid) if (zilog->zl_root_zio) { DTRACE_PROBE1(zil__cw3, zilog_t *, zilog); (void) zio_wait(zilog->zl_root_zio); + zilog->zl_root_zio = NULL; DTRACE_PROBE1(zil__cw4, zilog_t *, zilog); zil_flush_vdevs(zilog); } @@ -1251,20 +1340,20 @@ zil_free(zilog_t *zilog) /* * return true if the initial log block is not valid */ -static int +static boolean_t zil_empty(zilog_t *zilog) { const zil_header_t *zh = zilog->zl_header; arc_buf_t *abuf = NULL; if (BP_IS_HOLE(&zh->zh_log)) - return (1); + return (B_TRUE); if (zil_read_log_block(zilog, &zh->zh_log, &abuf) != 0) - return (1); + return (B_TRUE); VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1); - return (0); + return (B_FALSE); } /* @@ -1333,7 +1422,6 @@ zil_suspend(zilog_t *zilog) */ while (zilog->zl_suspending) cv_wait(&zilog->zl_cv_suspend, &zilog->zl_lock); - ASSERT(BP_IS_HOLE(&zh->zh_log)); mutex_exit(&zilog->zl_lock); return (0); } @@ -1372,6 +1460,7 @@ zil_resume(zilog_t *zilog) typedef struct zil_replay_arg { objset_t *zr_os; zil_replay_func_t **zr_replay; + zil_replay_cleaner_t *zr_replay_cleaner; void *zr_arg; uint64_t *zr_txgp; boolean_t zr_byteswap; @@ -1449,6 +1538,29 @@ zil_replay_log_record(zilog_t *zilog, lr_t *lr, void *zra, uint64_t claim_txg) } } + /* + * Replay of large truncates can end up needing additional txs + * and a different txg. If they are nested within the replay tx + * as below then a hang is possible. So we do the truncate here + * and redo the truncate later (a no-op) and update the sequence + * number whilst in the replay tx. Fortunately, it's safe to repeat + * a truncate if we crash and the truncate commits. A create over + * an existing file will also come in as a TX_TRUNCATE record. + * + * Note, remove of large files and renames over large files is + * handled by putting the deleted object on a stable list + * and if necessary force deleting the object outside of the replay + * transaction using the zr_replay_cleaner. + */ + if (txtype == TX_TRUNCATE) { + *zr->zr_txgp = TXG_NOWAIT; + error = zr->zr_replay[TX_TRUNCATE](zr->zr_arg, zr->zr_lrbuf, + zr->zr_byteswap); + if (error) + goto bad; + zr->zr_byteswap = 0; /* only byteswap once */ + } + /* * We must now do two things atomically: replay this log record, * and update the log header to reflect the fact that we did so. @@ -1502,6 +1614,8 @@ zil_replay_log_record(zilog_t *zilog, lr_t *lr, void *zra, uint64_t claim_txg) * transaction. */ if (error != ERESTART && !sunk) { + if (zr->zr_replay_cleaner) + zr->zr_replay_cleaner(zr->zr_arg); txg_wait_synced(spa_get_dsl(zilog->zl_spa), 0); sunk = B_TRUE; continue; /* retry */ @@ -1517,6 +1631,7 @@ zil_replay_log_record(zilog_t *zilog, lr_t *lr, void *zra, uint64_t claim_txg) dprintf("pass %d, retrying\n", pass); } +bad: ASSERT(error && error != ERESTART); name = kmem_alloc(MAXNAMELEN, KM_SLEEP); dmu_objset_name(zr->zr_os, name); @@ -1540,7 +1655,8 @@ zil_incr_blks(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg) */ void zil_replay(objset_t *os, void *arg, uint64_t *txgp, - zil_replay_func_t *replay_func[TX_MAX_TYPE]) + zil_replay_func_t *replay_func[TX_MAX_TYPE], + zil_replay_cleaner_t *replay_cleaner) { zilog_t *zilog = dmu_objset_zil(os); const zil_header_t *zh = zilog->zl_header; @@ -1553,6 +1669,7 @@ zil_replay(objset_t *os, void *arg, uint64_t *txgp, zr.zr_os = os; zr.zr_replay = replay_func; + zr.zr_replay_cleaner = replay_cleaner; zr.zr_arg = arg; zr.zr_txgp = txgp; zr.zr_byteswap = BP_SHOULD_BYTESWAP(&zh->zh_log); diff --git a/zfs/lib/libzpool/zio.c b/zfs/lib/libzpool/zio.c index 7eb44cbba..d347920ea 100644 --- a/zfs/lib/libzpool/zio.c +++ b/zfs/lib/libzpool/zio.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zio.c 1.32 08/03/20 SMI" - #include #include #include @@ -61,30 +59,9 @@ uint8_t zio_priority_table[ZIO_PRIORITY_TABLE_SIZE] = { char *zio_type_name[ZIO_TYPES] = { "null", "read", "write", "free", "claim", "ioctl" }; -/* Force an allocation failure when non-zero */ -uint16_t zio_zil_fail_shift = 0; -uint16_t zio_io_fail_shift = 0; - -/* Enable/disable the write-retry logic */ -int zio_write_retry = 1; - -/* Taskq to handle reissuing of I/Os */ -taskq_t *zio_taskq; -int zio_resume_threads = 4; - -typedef struct zio_sync_pass { - int zp_defer_free; /* defer frees after this pass */ - int zp_dontcompress; /* don't compress after this pass */ - int zp_rewrite; /* rewrite new bps after this pass */ -} zio_sync_pass_t; - -zio_sync_pass_t zio_sync_pass = { - 1, /* zp_defer_free */ - 4, /* zp_dontcompress */ - 1, /* zp_rewrite */ -}; - -static boolean_t zio_io_should_fail(uint16_t); +#define SYNC_PASS_DEFERRED_FREE 1 /* defer frees after this pass */ +#define SYNC_PASS_DONT_COMPRESS 4 /* don't compress after this pass */ +#define SYNC_PASS_REWRITE 1 /* rewrite new bps after this pass */ /* * ========================================================================== @@ -100,22 +77,8 @@ extern vmem_t *zio_alloc_arena; #endif /* - * Determine if we are allowed to issue the IO based on the - * pool state. If we must wait then block until we are told - * that we may continue. - */ -#define ZIO_ENTER(spa) { \ - if (spa->spa_state == POOL_STATE_IO_FAILURE) { \ - mutex_enter(&spa->spa_zio_lock); \ - while (spa->spa_state == POOL_STATE_IO_FAILURE) \ - cv_wait(&spa->spa_zio_cv, &spa->spa_zio_lock); \ - mutex_exit(&spa->spa_zio_lock); \ - } \ -} - -/* - * An allocation zio is one that either currently has the DVA allocate - * stage set or will have it later in it's lifetime. + * An allocating zio is one that either currently has the DVA allocate + * stage set or will have it later in its lifetime. */ #define IO_IS_ALLOCATING(zio) \ ((zio)->io_orig_pipeline & (1U << ZIO_STAGE_DVA_ALLOCATE)) @@ -129,7 +92,6 @@ zio_init(void) #ifdef _KERNEL data_alloc_arena = zio_alloc_arena; #endif - zio_cache = kmem_cache_create("zio_cache", sizeof (zio_t), 0, NULL, NULL, NULL, NULL, NULL, 0); @@ -165,7 +127,6 @@ zio_init(void) zio_data_buf_cache[c] = kmem_cache_create(name, size, align, NULL, NULL, NULL, NULL, data_alloc_arena, KMC_NODEBUG); - } } @@ -179,9 +140,6 @@ zio_init(void) zio_data_buf_cache[c - 1] = zio_data_buf_cache[c]; } - zio_taskq = taskq_create("zio_taskq", zio_resume_threads, - maxclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE); - zio_inject_init(); } @@ -206,8 +164,6 @@ zio_fini(void) zio_data_buf_cache[c] = NULL; } - taskq_destroy(zio_taskq); - kmem_cache_destroy(zio_cache); zio_inject_fini(); @@ -277,13 +233,15 @@ zio_data_buf_free(void *buf, size_t size) * ========================================================================== */ static void -zio_push_transform(zio_t *zio, void *data, uint64_t size, uint64_t bufsize) +zio_push_transform(zio_t *zio, void *data, uint64_t size, uint64_t bufsize, + zio_transform_func_t *transform) { zio_transform_t *zt = kmem_alloc(sizeof (zio_transform_t), KM_SLEEP); - zt->zt_data = data; - zt->zt_size = size; + zt->zt_orig_data = zio->io_data; + zt->zt_orig_size = zio->io_size; zt->zt_bufsize = bufsize; + zt->zt_transform = transform; zt->zt_next = zio->io_transform_stack; zio->io_transform_stack = zt; @@ -293,143 +251,231 @@ zio_push_transform(zio_t *zio, void *data, uint64_t size, uint64_t bufsize) } static void -zio_pop_transform(zio_t *zio, void **data, uint64_t *size, uint64_t *bufsize) +zio_pop_transforms(zio_t *zio) { - zio_transform_t *zt = zio->io_transform_stack; + zio_transform_t *zt; - *data = zt->zt_data; - *size = zt->zt_size; - *bufsize = zt->zt_bufsize; + while ((zt = zio->io_transform_stack) != NULL) { + if (zt->zt_transform != NULL) + zt->zt_transform(zio, + zt->zt_orig_data, zt->zt_orig_size); - zio->io_transform_stack = zt->zt_next; - kmem_free(zt, sizeof (zio_transform_t)); + zio_buf_free(zio->io_data, zt->zt_bufsize); - if ((zt = zio->io_transform_stack) != NULL) { - zio->io_data = zt->zt_data; - zio->io_size = zt->zt_size; - } -} + zio->io_data = zt->zt_orig_data; + zio->io_size = zt->zt_orig_size; + zio->io_transform_stack = zt->zt_next; -static void -zio_clear_transform_stack(zio_t *zio) -{ - void *data; - uint64_t size, bufsize; - - ASSERT(zio->io_transform_stack != NULL); - - zio_pop_transform(zio, &data, &size, &bufsize); - while (zio->io_transform_stack != NULL) { - zio_buf_free(data, bufsize); - zio_pop_transform(zio, &data, &size, &bufsize); + kmem_free(zt, sizeof (zio_transform_t)); } } /* * ========================================================================== - * Create the various types of I/O (read, write, free) + * I/O transform callbacks for subblocks and decompression + * ========================================================================== + */ +static void +zio_subblock(zio_t *zio, void *data, uint64_t size) +{ + ASSERT(zio->io_size > size); + + if (zio->io_type == ZIO_TYPE_READ) + bcopy(zio->io_data, data, size); +} + +static void +zio_decompress(zio_t *zio, void *data, uint64_t size) +{ + if (zio->io_error == 0 && + zio_decompress_data(BP_GET_COMPRESS(zio->io_bp), + zio->io_data, zio->io_size, data, size) != 0) + zio->io_error = EIO; +} + +/* + * ========================================================================== + * I/O parent/child relationships and pipeline interlocks + * ========================================================================== + */ + +static void +zio_add_child(zio_t *pio, zio_t *zio) +{ + mutex_enter(&pio->io_lock); + if (zio->io_stage < ZIO_STAGE_READY) + pio->io_children[zio->io_child_type][ZIO_WAIT_READY]++; + if (zio->io_stage < ZIO_STAGE_DONE) + pio->io_children[zio->io_child_type][ZIO_WAIT_DONE]++; + zio->io_sibling_prev = NULL; + zio->io_sibling_next = pio->io_child; + if (pio->io_child != NULL) + pio->io_child->io_sibling_prev = zio; + pio->io_child = zio; + zio->io_parent = pio; + mutex_exit(&pio->io_lock); +} + +static void +zio_remove_child(zio_t *pio, zio_t *zio) +{ + zio_t *next, *prev; + + ASSERT(zio->io_parent == pio); + + mutex_enter(&pio->io_lock); + next = zio->io_sibling_next; + prev = zio->io_sibling_prev; + if (next != NULL) + next->io_sibling_prev = prev; + if (prev != NULL) + prev->io_sibling_next = next; + if (pio->io_child == zio) + pio->io_child = next; + mutex_exit(&pio->io_lock); +} + +static boolean_t +zio_wait_for_children(zio_t *zio, enum zio_child child, enum zio_wait_type wait) +{ + uint64_t *countp = &zio->io_children[child][wait]; + boolean_t waiting = B_FALSE; + + mutex_enter(&zio->io_lock); + ASSERT(zio->io_stall == NULL); + if (*countp != 0) { + zio->io_stage--; + zio->io_stall = countp; + waiting = B_TRUE; + } + mutex_exit(&zio->io_lock); + + return (waiting); +} + +static void +zio_notify_parent(zio_t *pio, zio_t *zio, enum zio_wait_type wait) +{ + uint64_t *countp = &pio->io_children[zio->io_child_type][wait]; + int *errorp = &pio->io_child_error[zio->io_child_type]; + + mutex_enter(&pio->io_lock); + if (zio->io_error && !(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE)) + *errorp = zio_worst_error(*errorp, zio->io_error); + pio->io_reexecute |= zio->io_reexecute; + ASSERT3U(*countp, >, 0); + if (--*countp == 0 && pio->io_stall == countp) { + pio->io_stall = NULL; + mutex_exit(&pio->io_lock); + zio_execute(pio); + } else { + mutex_exit(&pio->io_lock); + } +} + +static void +zio_inherit_child_errors(zio_t *zio, enum zio_child c) +{ + if (zio->io_child_error[c] != 0 && zio->io_error == 0) + zio->io_error = zio->io_child_error[c]; +} + +/* + * ========================================================================== + * Create the various types of I/O (read, write, free, etc) * ========================================================================== */ static zio_t * zio_create(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, void *data, uint64_t size, zio_done_func_t *done, void *private, - zio_type_t type, int priority, int flags, uint8_t stage, uint32_t pipeline) + zio_type_t type, int priority, int flags, vdev_t *vd, uint64_t offset, + const zbookmark_t *zb, uint8_t stage, uint32_t pipeline) { zio_t *zio; ASSERT3U(size, <=, SPA_MAXBLOCKSIZE); ASSERT(P2PHASE(size, SPA_MINBLOCKSIZE) == 0); + ASSERT(P2PHASE(offset, SPA_MINBLOCKSIZE) == 0); + + ASSERT(!vd || spa_config_held(spa, SCL_STATE_ALL, RW_READER)); + ASSERT(!bp || !(flags & ZIO_FLAG_CONFIG_WRITER)); + ASSERT(vd || stage == ZIO_STAGE_OPEN); zio = kmem_cache_alloc(zio_cache, KM_SLEEP); bzero(zio, sizeof (zio_t)); - zio->io_parent = pio; - zio->io_spa = spa; - zio->io_txg = txg; - zio->io_flags = flags; + + mutex_init(&zio->io_lock, NULL, MUTEX_DEFAULT, NULL); + cv_init(&zio->io_cv, NULL, CV_DEFAULT, NULL); + + if (vd != NULL) + zio->io_child_type = ZIO_CHILD_VDEV; + else if (flags & ZIO_FLAG_GANG_CHILD) + zio->io_child_type = ZIO_CHILD_GANG; + else + zio->io_child_type = ZIO_CHILD_LOGICAL; + if (bp != NULL) { zio->io_bp = bp; zio->io_bp_copy = *bp; zio->io_bp_orig = *bp; + if (type != ZIO_TYPE_WRITE) + zio->io_bp = &zio->io_bp_copy; /* so caller can free */ + if (zio->io_child_type == ZIO_CHILD_LOGICAL) { + if (BP_IS_GANG(bp)) + pipeline |= ZIO_GANG_STAGES; + zio->io_logical = zio; + } } + + zio->io_spa = spa; + zio->io_txg = txg; + zio->io_data = data; + zio->io_size = size; zio->io_done = done; zio->io_private = private; zio->io_type = type; zio->io_priority = priority; - zio->io_stage = stage; - zio->io_pipeline = pipeline; - zio->io_timestamp = lbolt64; - mutex_init(&zio->io_lock, NULL, MUTEX_DEFAULT, NULL); - cv_init(&zio->io_cv, NULL, CV_DEFAULT, NULL); - zio_push_transform(zio, data, size, size); + zio->io_vd = vd; + zio->io_offset = offset; + zio->io_orig_flags = zio->io_flags = flags; + zio->io_orig_stage = zio->io_stage = stage; + zio->io_orig_pipeline = zio->io_pipeline = pipeline; - /* - * Note on config lock: - * - * If CONFIG_HELD is set, then the caller already has the config - * lock, so we don't need it for this io. - * - * We set CONFIG_GRABBED to indicate that we have grabbed the - * config lock on behalf of this io, so it should be released - * in zio_done. - * - * Unless CONFIG_HELD is set, we will grab the config lock for - * any top-level (parent-less) io, *except* NULL top-level ios. - * The NULL top-level ios rarely have any children, so we delay - * grabbing the lock until the first child is added (but it is - * still grabbed on behalf of the top-level i/o, so additional - * children don't need to also grab it). This greatly reduces - * contention on the config lock. - */ - if (pio == NULL) { - if (type != ZIO_TYPE_NULL && - !(flags & ZIO_FLAG_CONFIG_HELD)) { - spa_config_enter(spa, RW_READER, zio); - zio->io_flags |= ZIO_FLAG_CONFIG_GRABBED; - } - zio->io_root = zio; - } else { - zio->io_root = pio->io_root; - if (!(flags & ZIO_FLAG_NOBOOKMARK)) + if (zb != NULL) + zio->io_bookmark = *zb; + + if (pio != NULL) { + /* + * Logical I/Os can have logical, gang, or vdev children. + * Gang I/Os can have gang or vdev children. + * Vdev I/Os can only have vdev children. + * The following ASSERT captures all of these constraints. + */ + ASSERT(zio->io_child_type <= pio->io_child_type); + if (zio->io_logical == NULL) zio->io_logical = pio->io_logical; - mutex_enter(&pio->io_lock); - if (pio->io_parent == NULL && - pio->io_type == ZIO_TYPE_NULL && - !(pio->io_flags & ZIO_FLAG_CONFIG_GRABBED) && - !(pio->io_flags & ZIO_FLAG_CONFIG_HELD)) { - pio->io_flags |= ZIO_FLAG_CONFIG_GRABBED; - spa_config_enter(spa, RW_READER, pio); - } - if (stage < ZIO_STAGE_READY) - pio->io_children_notready++; - pio->io_children_notdone++; - zio->io_sibling_next = pio->io_child; - zio->io_sibling_prev = NULL; - if (pio->io_child != NULL) - pio->io_child->io_sibling_prev = zio; - pio->io_child = zio; - zio->io_ndvas = pio->io_ndvas; - mutex_exit(&pio->io_lock); + zio_add_child(pio, zio); } - /* - * Save off the original state incase we need to retry later. - */ - zio->io_orig_stage = zio->io_stage; - zio->io_orig_pipeline = zio->io_pipeline; - zio->io_orig_flags = zio->io_flags; - return (zio); } static void -zio_reset(zio_t *zio) +zio_destroy(zio_t *zio) { - zio_clear_transform_stack(zio); + spa_t *spa = zio->io_spa; + uint8_t async_root = zio->io_async_root; - zio->io_flags = zio->io_orig_flags; - zio->io_stage = zio->io_orig_stage; - zio->io_pipeline = zio->io_orig_pipeline; - zio_push_transform(zio, zio->io_data, zio->io_size, zio->io_size); + mutex_destroy(&zio->io_lock); + cv_destroy(&zio->io_cv); + kmem_cache_free(zio_cache, zio); + + if (async_root) { + mutex_enter(&spa->spa_async_root_lock); + if (--spa->spa_async_root_count == 0) + cv_broadcast(&spa->spa_async_root_cv); + mutex_exit(&spa->spa_async_root_lock); + } } zio_t * @@ -439,8 +485,8 @@ zio_null(zio_t *pio, spa_t *spa, zio_done_func_t *done, void *private, zio_t *zio; zio = zio_create(pio, spa, 0, NULL, NULL, 0, done, private, - ZIO_TYPE_NULL, ZIO_PRIORITY_NOW, flags, ZIO_STAGE_OPEN, - ZIO_WAIT_FOR_CHILDREN_PIPELINE); + ZIO_TYPE_NULL, ZIO_PRIORITY_NOW, flags, NULL, 0, NULL, + ZIO_STAGE_OPEN, ZIO_INTERLOCK_PIPELINE); return (zio); } @@ -452,161 +498,99 @@ zio_root(spa_t *spa, zio_done_func_t *done, void *private, int flags) } zio_t * -zio_read(zio_t *pio, spa_t *spa, blkptr_t *bp, void *data, - uint64_t size, zio_done_func_t *done, void *private, - int priority, int flags, zbookmark_t *zb) +zio_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, + void *data, uint64_t size, zio_done_func_t *done, void *private, + int priority, int flags, const zbookmark_t *zb) { zio_t *zio; - ASSERT3U(size, ==, BP_GET_LSIZE(bp)); - - /* - * If the user has specified that we allow I/Os to continue - * then attempt to satisfy the read. - */ - if (spa_get_failmode(spa) != ZIO_FAILURE_MODE_CONTINUE) - ZIO_ENTER(spa); - - zio = zio_create(pio, spa, bp->blk_birth, bp, data, size, done, private, - ZIO_TYPE_READ, priority, flags | ZIO_FLAG_USER, + zio = zio_create(pio, spa, bp->blk_birth, (blkptr_t *)bp, + data, size, done, private, + ZIO_TYPE_READ, priority, flags, NULL, 0, zb, ZIO_STAGE_OPEN, ZIO_READ_PIPELINE); - zio->io_bookmark = *zb; - zio->io_logical = zio; + return (zio); +} - /* - * Work off our copy of the bp so the caller can free it. - */ - zio->io_bp = &zio->io_bp_copy; +void +zio_skip_write(zio_t *zio) +{ + ASSERT(zio->io_type == ZIO_TYPE_WRITE); + ASSERT(zio->io_stage == ZIO_STAGE_READY); + ASSERT(!BP_IS_GANG(zio->io_bp)); + + zio->io_pipeline &= ~ZIO_VDEV_IO_STAGES; +} + +zio_t * +zio_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, + void *data, uint64_t size, zio_prop_t *zp, + zio_done_func_t *ready, zio_done_func_t *done, void *private, + int priority, int flags, const zbookmark_t *zb) +{ + zio_t *zio; + + ASSERT(zp->zp_checksum >= ZIO_CHECKSUM_OFF && + zp->zp_checksum < ZIO_CHECKSUM_FUNCTIONS && + zp->zp_compress >= ZIO_COMPRESS_OFF && + zp->zp_compress < ZIO_COMPRESS_FUNCTIONS && + zp->zp_type < DMU_OT_NUMTYPES && + zp->zp_level < 32 && + zp->zp_ndvas > 0 && + zp->zp_ndvas <= spa_max_replication(spa)); + ASSERT(ready != NULL); + + zio = zio_create(pio, spa, txg, bp, data, size, done, private, + ZIO_TYPE_WRITE, priority, flags, NULL, 0, zb, + ZIO_STAGE_OPEN, ZIO_WRITE_PIPELINE); + + zio->io_ready = ready; + zio->io_prop = *zp; return (zio); } zio_t * -zio_write(zio_t *pio, spa_t *spa, int checksum, int compress, int ncopies, - uint64_t txg, blkptr_t *bp, void *data, uint64_t size, - zio_done_func_t *ready, zio_done_func_t *done, void *private, int priority, +zio_rewrite(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, void *data, + uint64_t size, zio_done_func_t *done, void *private, int priority, int flags, zbookmark_t *zb) { zio_t *zio; - ASSERT(checksum >= ZIO_CHECKSUM_OFF && - checksum < ZIO_CHECKSUM_FUNCTIONS); - - ASSERT(compress >= ZIO_COMPRESS_OFF && - compress < ZIO_COMPRESS_FUNCTIONS); - - ZIO_ENTER(spa); - zio = zio_create(pio, spa, txg, bp, data, size, done, private, - ZIO_TYPE_WRITE, priority, flags | ZIO_FLAG_USER, - ZIO_STAGE_OPEN, ZIO_WRITE_PIPELINE); - - zio->io_ready = ready; - - zio->io_bookmark = *zb; - - zio->io_logical = zio; - - zio->io_checksum = checksum; - zio->io_compress = compress; - zio->io_ndvas = ncopies; - - if (bp->blk_birth != txg) { - /* XXX the bp usually (always?) gets re-zeroed later */ - BP_ZERO(bp); - BP_SET_LSIZE(bp, size); - BP_SET_PSIZE(bp, size); - } else { - /* Make sure someone doesn't change their mind on overwrites */ - ASSERT(MIN(zio->io_ndvas + BP_IS_GANG(bp), - spa_max_replication(spa)) == BP_GET_NDVAS(bp)); - } - - return (zio); -} - -zio_t * -zio_rewrite(zio_t *pio, spa_t *spa, int checksum, - uint64_t txg, blkptr_t *bp, void *data, uint64_t size, - zio_done_func_t *done, void *private, int priority, int flags, - zbookmark_t *zb) -{ - zio_t *zio; - - zio = zio_create(pio, spa, txg, bp, data, size, done, private, - ZIO_TYPE_WRITE, priority, flags | ZIO_FLAG_USER, - ZIO_STAGE_OPEN, ZIO_REWRITE_PIPELINE(bp)); - - zio->io_bookmark = *zb; - zio->io_checksum = checksum; - zio->io_compress = ZIO_COMPRESS_OFF; - - if (pio != NULL) - ASSERT3U(zio->io_ndvas, <=, BP_GET_NDVAS(bp)); - - return (zio); -} - -static void -zio_write_allocate_ready(zio_t *zio) -{ - /* Free up the previous block */ - if (!BP_IS_HOLE(&zio->io_bp_orig)) { - zio_nowait(zio_free(zio, zio->io_spa, zio->io_txg, - &zio->io_bp_orig, NULL, NULL)); - } -} - -static zio_t * -zio_write_allocate(zio_t *pio, spa_t *spa, int checksum, - uint64_t txg, blkptr_t *bp, void *data, uint64_t size, - zio_done_func_t *done, void *private, int priority, int flags) -{ - zio_t *zio; - - BP_ZERO(bp); - BP_SET_LSIZE(bp, size); - BP_SET_PSIZE(bp, size); - BP_SET_COMPRESS(bp, ZIO_COMPRESS_OFF); - - zio = zio_create(pio, spa, txg, bp, data, size, done, private, - ZIO_TYPE_WRITE, priority, flags, - ZIO_STAGE_OPEN, ZIO_WRITE_ALLOCATE_PIPELINE); - - zio->io_checksum = checksum; - zio->io_compress = ZIO_COMPRESS_OFF; - zio->io_ready = zio_write_allocate_ready; + ZIO_TYPE_WRITE, priority, flags, NULL, 0, zb, + ZIO_STAGE_OPEN, ZIO_REWRITE_PIPELINE); return (zio); } zio_t * zio_free(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, - zio_done_func_t *done, void *private) + zio_done_func_t *done, void *private, int flags) { zio_t *zio; ASSERT(!BP_IS_HOLE(bp)); + if (bp->blk_fill == BLK_FILL_ALREADY_FREED) + return (zio_null(pio, spa, NULL, NULL, flags)); + if (txg == spa->spa_syncing_txg && - spa->spa_sync_pass > zio_sync_pass.zp_defer_free) { + spa_sync_pass(spa) > SYNC_PASS_DEFERRED_FREE) { bplist_enqueue_deferred(&spa->spa_sync_bplist, bp); - return (zio_null(pio, spa, NULL, NULL, 0)); + return (zio_null(pio, spa, NULL, NULL, flags)); } - zio = zio_create(pio, spa, txg, bp, NULL, 0, done, private, - ZIO_TYPE_FREE, ZIO_PRIORITY_FREE, ZIO_FLAG_USER, - ZIO_STAGE_OPEN, ZIO_FREE_PIPELINE(bp)); - - zio->io_bp = &zio->io_bp_copy; + zio = zio_create(pio, spa, txg, bp, NULL, BP_GET_PSIZE(bp), + done, private, ZIO_TYPE_FREE, ZIO_PRIORITY_FREE, flags, + NULL, 0, NULL, ZIO_STAGE_OPEN, ZIO_FREE_PIPELINE); return (zio); } zio_t * zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, - zio_done_func_t *done, void *private) + zio_done_func_t *done, void *private, int flags) { zio_t *zio; @@ -624,11 +608,9 @@ zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, ASSERT3U(spa->spa_uberblock.ub_rootbp.blk_birth, <, spa_first_txg(spa)); ASSERT3U(spa_first_txg(spa), <=, txg); - zio = zio_create(pio, spa, txg, bp, NULL, 0, done, private, - ZIO_TYPE_CLAIM, ZIO_PRIORITY_NOW, 0, - ZIO_STAGE_OPEN, ZIO_CLAIM_PIPELINE(bp)); - - zio->io_bp = &zio->io_bp_copy; + zio = zio_create(pio, spa, txg, bp, NULL, BP_GET_PSIZE(bp), + done, private, ZIO_TYPE_CLAIM, ZIO_PRIORITY_NOW, flags, + NULL, 0, NULL, ZIO_STAGE_OPEN, ZIO_CLAIM_PIPELINE); return (zio); } @@ -642,10 +624,9 @@ zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd, if (vd->vdev_children == 0) { zio = zio_create(pio, spa, 0, NULL, NULL, 0, done, private, - ZIO_TYPE_IOCTL, priority, flags, + ZIO_TYPE_IOCTL, priority, flags, vd, 0, NULL, ZIO_STAGE_OPEN, ZIO_IOCTL_PIPELINE); - zio->io_vd = vd; zio->io_cmd = cmd; } else { zio = zio_null(pio, spa, NULL, NULL, flags); @@ -658,60 +639,23 @@ zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd, return (zio); } -static void -zio_phys_bp_init(vdev_t *vd, blkptr_t *bp, uint64_t offset, uint64_t size, - int checksum, boolean_t labels) -{ - ASSERT(vd->vdev_children == 0); - - ASSERT(size <= SPA_MAXBLOCKSIZE); - ASSERT(P2PHASE(size, SPA_MINBLOCKSIZE) == 0); - ASSERT(P2PHASE(offset, SPA_MINBLOCKSIZE) == 0); - -#ifdef ZFS_DEBUG - if (labels) { - ASSERT(offset + size <= VDEV_LABEL_START_SIZE || - offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE); - } -#endif - ASSERT3U(offset + size, <=, vd->vdev_psize); - - BP_ZERO(bp); - - BP_SET_LSIZE(bp, size); - BP_SET_PSIZE(bp, size); - - BP_SET_CHECKSUM(bp, checksum); - BP_SET_COMPRESS(bp, ZIO_COMPRESS_OFF); - BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER); - - if (checksum != ZIO_CHECKSUM_OFF) - ZIO_SET_CHECKSUM(&bp->blk_cksum, offset, 0, 0, 0); -} - zio_t * zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size, void *data, int checksum, zio_done_func_t *done, void *private, int priority, int flags, boolean_t labels) { zio_t *zio; - blkptr_t blk; - ZIO_ENTER(vd->vdev_spa); + ASSERT(vd->vdev_children == 0); + ASSERT(!labels || offset + size <= VDEV_LABEL_START_SIZE || + offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE); + ASSERT3U(offset + size, <=, vd->vdev_psize); - zio_phys_bp_init(vd, &blk, offset, size, checksum, labels); - - zio = zio_create(pio, vd->vdev_spa, 0, &blk, data, size, done, private, - ZIO_TYPE_READ, priority, flags | ZIO_FLAG_PHYSICAL, + zio = zio_create(pio, vd->vdev_spa, 0, NULL, data, size, done, private, + ZIO_TYPE_READ, priority, flags, vd, offset, NULL, ZIO_STAGE_OPEN, ZIO_READ_PHYS_PIPELINE); - zio->io_vd = vd; - zio->io_offset = offset; - - /* - * Work off our copy of the bp so the caller can free it. - */ - zio->io_bp = &zio->io_bp_copy; + zio->io_prop.zp_checksum = checksum; return (zio); } @@ -721,53 +665,47 @@ zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size, void *data, int checksum, zio_done_func_t *done, void *private, int priority, int flags, boolean_t labels) { - zio_block_tail_t *zbt; - void *wbuf; zio_t *zio; - blkptr_t blk; - ZIO_ENTER(vd->vdev_spa); + ASSERT(vd->vdev_children == 0); + ASSERT(!labels || offset + size <= VDEV_LABEL_START_SIZE || + offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE); + ASSERT3U(offset + size, <=, vd->vdev_psize); - zio_phys_bp_init(vd, &blk, offset, size, checksum, labels); - - zio = zio_create(pio, vd->vdev_spa, 0, &blk, data, size, done, private, - ZIO_TYPE_WRITE, priority, flags | ZIO_FLAG_PHYSICAL, + zio = zio_create(pio, vd->vdev_spa, 0, NULL, data, size, done, private, + ZIO_TYPE_WRITE, priority, flags, vd, offset, NULL, ZIO_STAGE_OPEN, ZIO_WRITE_PHYS_PIPELINE); - zio->io_vd = vd; - zio->io_offset = offset; - - zio->io_bp = &zio->io_bp_copy; - zio->io_checksum = checksum; + zio->io_prop.zp_checksum = checksum; if (zio_checksum_table[checksum].ci_zbt) { /* * zbt checksums are necessarily destructive -- they modify - * one word of the write buffer to hold the verifier/checksum. + * the end of the write buffer to hold the verifier/checksum. * Therefore, we must make a local copy in case the data is - * being written to multiple places. + * being written to multiple places in parallel. */ - wbuf = zio_buf_alloc(size); + void *wbuf = zio_buf_alloc(size); bcopy(data, wbuf, size); - zio_push_transform(zio, wbuf, size, size); - - zbt = (zio_block_tail_t *)((char *)wbuf + size) - 1; - zbt->zbt_cksum = blk.blk_cksum; + zio_push_transform(zio, wbuf, size, size, NULL); } return (zio); } /* - * Create a child I/O to do some work for us. It has no associated bp. + * Create a child I/O to do some work for us. */ zio_t * -zio_vdev_child_io(zio_t *zio, blkptr_t *bp, vdev_t *vd, uint64_t offset, +zio_vdev_child_io(zio_t *pio, blkptr_t *bp, vdev_t *vd, uint64_t offset, void *data, uint64_t size, int type, int priority, int flags, zio_done_func_t *done, void *private) { uint32_t pipeline = ZIO_VDEV_CHILD_PIPELINE; - zio_t *cio; + zio_t *zio; + + ASSERT(vd->vdev_parent == + (pio->io_vd ? pio->io_vd : pio->io_spa->spa_root_vdev)); if (type == ZIO_TYPE_READ && bp != NULL) { /* @@ -777,18 +715,275 @@ zio_vdev_child_io(zio_t *zio, blkptr_t *bp, vdev_t *vd, uint64_t offset, * eliminates redundant checksums in the interior nodes. */ pipeline |= 1U << ZIO_STAGE_CHECKSUM_VERIFY; - zio->io_pipeline &= ~(1U << ZIO_STAGE_CHECKSUM_VERIFY); + pio->io_pipeline &= ~(1U << ZIO_STAGE_CHECKSUM_VERIFY); } - cio = zio_create(zio, zio->io_spa, zio->io_txg, bp, data, size, + if (vd->vdev_children == 0) + offset += VDEV_LABEL_START_SIZE; + + zio = zio_create(pio, pio->io_spa, pio->io_txg, bp, data, size, done, private, type, priority, - (zio->io_flags & ZIO_FLAG_VDEV_INHERIT) | ZIO_FLAG_CANFAIL | flags, + (pio->io_flags & ZIO_FLAG_VDEV_INHERIT) | + ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | flags, + vd, offset, &pio->io_bookmark, ZIO_STAGE_VDEV_IO_START - 1, pipeline); - cio->io_vd = vd; - cio->io_offset = offset; + return (zio); +} - return (cio); +zio_t * +zio_vdev_delegated_io(vdev_t *vd, uint64_t offset, void *data, uint64_t size, + int type, int priority, int flags, zio_done_func_t *done, void *private) +{ + zio_t *zio; + + ASSERT(vd->vdev_ops->vdev_op_leaf); + + zio = zio_create(NULL, vd->vdev_spa, 0, NULL, + data, size, done, private, type, priority, + flags | ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_RETRY, + vd, offset, NULL, + ZIO_STAGE_VDEV_IO_START - 1, ZIO_VDEV_CHILD_PIPELINE); + + return (zio); +} + +void +zio_flush(zio_t *zio, vdev_t *vd) +{ + zio_nowait(zio_ioctl(zio, zio->io_spa, vd, DKIOCFLUSHWRITECACHE, + NULL, NULL, ZIO_PRIORITY_NOW, + ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY)); +} + +/* + * ========================================================================== + * Prepare to read and write logical blocks + * ========================================================================== + */ + +static int +zio_read_bp_init(zio_t *zio) +{ + blkptr_t *bp = zio->io_bp; + + if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF && zio->io_logical == zio) { + uint64_t csize = BP_GET_PSIZE(bp); + void *cbuf = zio_buf_alloc(csize); + + zio_push_transform(zio, cbuf, csize, csize, zio_decompress); + } + + if (!dmu_ot[BP_GET_TYPE(bp)].ot_metadata && BP_GET_LEVEL(bp) == 0) + zio->io_flags |= ZIO_FLAG_DONT_CACHE; + + return (ZIO_PIPELINE_CONTINUE); +} + +static int +zio_write_bp_init(zio_t *zio) +{ + zio_prop_t *zp = &zio->io_prop; + int compress = zp->zp_compress; + blkptr_t *bp = zio->io_bp; + void *cbuf; + uint64_t lsize = zio->io_size; + uint64_t csize = lsize; + uint64_t cbufsize = 0; + int pass = 1; + + /* + * If our children haven't all reached the ready stage, + * wait for them and then repeat this pipeline stage. + */ + if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_READY) || + zio_wait_for_children(zio, ZIO_CHILD_LOGICAL, ZIO_WAIT_READY)) + return (ZIO_PIPELINE_STOP); + + if (!IO_IS_ALLOCATING(zio)) + return (ZIO_PIPELINE_CONTINUE); + + ASSERT(compress != ZIO_COMPRESS_INHERIT); + + if (bp->blk_birth == zio->io_txg) { + /* + * We're rewriting an existing block, which means we're + * working on behalf of spa_sync(). For spa_sync() to + * converge, it must eventually be the case that we don't + * have to allocate new blocks. But compression changes + * the blocksize, which forces a reallocate, and makes + * convergence take longer. Therefore, after the first + * few passes, stop compressing to ensure convergence. + */ + pass = spa_sync_pass(zio->io_spa); + ASSERT(pass > 1); + + if (pass > SYNC_PASS_DONT_COMPRESS) + compress = ZIO_COMPRESS_OFF; + + /* + * Only MOS (objset 0) data should need to be rewritten. + */ + ASSERT(zio->io_logical->io_bookmark.zb_objset == 0); + + /* Make sure someone doesn't change their mind on overwrites */ + ASSERT(MIN(zp->zp_ndvas + BP_IS_GANG(bp), + spa_max_replication(zio->io_spa)) == BP_GET_NDVAS(bp)); + } + + if (compress != ZIO_COMPRESS_OFF) { + if (!zio_compress_data(compress, zio->io_data, zio->io_size, + &cbuf, &csize, &cbufsize)) { + compress = ZIO_COMPRESS_OFF; + } else if (csize != 0) { + zio_push_transform(zio, cbuf, csize, cbufsize, NULL); + } + } + + /* + * The final pass of spa_sync() must be all rewrites, but the first + * few passes offer a trade-off: allocating blocks defers convergence, + * but newly allocated blocks are sequential, so they can be written + * to disk faster. Therefore, we allow the first few passes of + * spa_sync() to allocate new blocks, but force rewrites after that. + * There should only be a handful of blocks after pass 1 in any case. + */ + if (bp->blk_birth == zio->io_txg && BP_GET_PSIZE(bp) == csize && + pass > SYNC_PASS_REWRITE) { + ASSERT(csize != 0); + uint32_t gang_stages = zio->io_pipeline & ZIO_GANG_STAGES; + zio->io_pipeline = ZIO_REWRITE_PIPELINE | gang_stages; + zio->io_flags |= ZIO_FLAG_IO_REWRITE; + } else { + BP_ZERO(bp); + zio->io_pipeline = ZIO_WRITE_PIPELINE; + } + + if (csize == 0) { + zio->io_pipeline = ZIO_INTERLOCK_PIPELINE; + } else { + ASSERT(zp->zp_checksum != ZIO_CHECKSUM_GANG_HEADER); + BP_SET_LSIZE(bp, lsize); + BP_SET_PSIZE(bp, csize); + BP_SET_COMPRESS(bp, compress); + BP_SET_CHECKSUM(bp, zp->zp_checksum); + BP_SET_TYPE(bp, zp->zp_type); + BP_SET_LEVEL(bp, zp->zp_level); + BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER); + } + + return (ZIO_PIPELINE_CONTINUE); +} + +/* + * ========================================================================== + * Execute the I/O pipeline + * ========================================================================== + */ + +static void +zio_taskq_dispatch(zio_t *zio, enum zio_taskq_type q) +{ + zio_type_t t = zio->io_type; + + /* + * If we're a config writer, the normal issue and interrupt threads + * may all be blocked waiting for the config lock. In this case, + * select the otherwise-unused taskq for ZIO_TYPE_NULL. + */ + if (zio->io_flags & ZIO_FLAG_CONFIG_WRITER) + t = ZIO_TYPE_NULL; + + /* + * A similar issue exists for the L2ARC write thread until L2ARC 2.0. + */ + if (t == ZIO_TYPE_WRITE && zio->io_vd && zio->io_vd->vdev_aux) + t = ZIO_TYPE_NULL; + + (void) taskq_dispatch(zio->io_spa->spa_zio_taskq[t][q], + (task_func_t *)zio_execute, zio, TQ_SLEEP); +} + +static boolean_t +zio_taskq_member(zio_t *zio, enum zio_taskq_type q) +{ + kthread_t *executor = zio->io_executor; + spa_t *spa = zio->io_spa; + + for (zio_type_t t = 0; t < ZIO_TYPES; t++) + if (taskq_member(spa->spa_zio_taskq[t][q], executor)) + return (B_TRUE); + + return (B_FALSE); +} + +static int +zio_issue_async(zio_t *zio) +{ + zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE); + + return (ZIO_PIPELINE_STOP); +} + +void +zio_interrupt(zio_t *zio) +{ + zio_taskq_dispatch(zio, ZIO_TASKQ_INTERRUPT); +} + +/* + * Execute the I/O pipeline until one of the following occurs: + * (1) the I/O completes; (2) the pipeline stalls waiting for + * dependent child I/Os; (3) the I/O issues, so we're waiting + * for an I/O completion interrupt; (4) the I/O is delegated by + * vdev-level caching or aggregation; (5) the I/O is deferred + * due to vdev-level queueing; (6) the I/O is handed off to + * another thread. In all cases, the pipeline stops whenever + * there's no CPU work; it never burns a thread in cv_wait(). + * + * There's no locking on io_stage because there's no legitimate way + * for multiple threads to be attempting to process the same I/O. + */ +static zio_pipe_stage_t *zio_pipeline[ZIO_STAGES]; + +void +zio_execute(zio_t *zio) +{ + zio->io_executor = curthread; + + while (zio->io_stage < ZIO_STAGE_DONE) { + uint32_t pipeline = zio->io_pipeline; + zio_stage_t stage = zio->io_stage; + int rv; + + ASSERT(!MUTEX_HELD(&zio->io_lock)); + + while (((1U << ++stage) & pipeline) == 0) + continue; + + ASSERT(stage <= ZIO_STAGE_DONE); + ASSERT(zio->io_stall == NULL); + + /* + * If we are in interrupt context and this pipeline stage + * will grab a config lock that is held across I/O, + * issue async to avoid deadlock. + */ + if (((1U << stage) & ZIO_CONFIG_LOCK_BLOCKING_STAGES) && + zio->io_vd == NULL && + zio_taskq_member(zio, ZIO_TASKQ_INTERRUPT)) { + zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE); + return; + } + + zio->io_stage = stage; + rv = zio_pipeline[stage](zio); + + if (rv == ZIO_PIPELINE_STOP) + return; + + ASSERT(rv == ZIO_PIPELINE_CONTINUE); + } } /* @@ -802,20 +997,19 @@ zio_wait(zio_t *zio) int error; ASSERT(zio->io_stage == ZIO_STAGE_OPEN); + ASSERT(zio->io_executor == NULL); zio->io_waiter = curthread; zio_execute(zio); mutex_enter(&zio->io_lock); - while (zio->io_stalled != ZIO_STAGE_DONE) + while (zio->io_executor != NULL) cv_wait(&zio->io_cv, &zio->io_lock); mutex_exit(&zio->io_lock); error = zio->io_error; - mutex_destroy(&zio->io_lock); - cv_destroy(&zio->io_cv); - kmem_cache_free(zio_cache, zio); + zio_destroy(zio); return (error); } @@ -823,703 +1017,452 @@ zio_wait(zio_t *zio) void zio_nowait(zio_t *zio) { + ASSERT(zio->io_executor == NULL); + + if (zio->io_parent == NULL && zio->io_child_type == ZIO_CHILD_LOGICAL) { + /* + * This is a logical async I/O with no parent to wait for it. + * Attach it to the pool's global async root zio so that + * spa_unload() has a way of waiting for async I/O to finish. + */ + spa_t *spa = zio->io_spa; + zio->io_async_root = B_TRUE; + mutex_enter(&spa->spa_async_root_lock); + spa->spa_async_root_count++; + mutex_exit(&spa->spa_async_root_lock); + } + zio_execute(zio); } -void -zio_interrupt(zio_t *zio) +/* + * ========================================================================== + * Reexecute or suspend/resume failed I/O + * ========================================================================== + */ + +static void +zio_reexecute(zio_t *pio) { - (void) taskq_dispatch(zio->io_spa->spa_zio_intr_taskq[zio->io_type], - (task_func_t *)zio_execute, zio, TQ_SLEEP); + zio_t *zio, *zio_next; + + pio->io_flags = pio->io_orig_flags; + pio->io_stage = pio->io_orig_stage; + pio->io_pipeline = pio->io_orig_pipeline; + pio->io_reexecute = 0; + pio->io_error = 0; + for (int c = 0; c < ZIO_CHILD_TYPES; c++) + pio->io_child_error[c] = 0; + + if (IO_IS_ALLOCATING(pio)) { + /* + * Remember the failed bp so that the io_ready() callback + * can update its accounting upon reexecution. The block + * was already freed in zio_done(); we indicate this with + * a fill count of -1 so that zio_free() knows to skip it. + */ + blkptr_t *bp = pio->io_bp; + ASSERT(bp->blk_birth == 0 || bp->blk_birth == pio->io_txg); + bp->blk_fill = BLK_FILL_ALREADY_FREED; + pio->io_bp_orig = *bp; + BP_ZERO(bp); + } + + /* + * As we reexecute pio's children, new children could be created. + * New children go to the head of the io_child list, however, + * so we will (correctly) not reexecute them. The key is that + * the remainder of the io_child list, from 'zio_next' onward, + * cannot be affected by any side effects of reexecuting 'zio'. + */ + for (zio = pio->io_child; zio != NULL; zio = zio_next) { + zio_next = zio->io_sibling_next; + mutex_enter(&pio->io_lock); + pio->io_children[zio->io_child_type][ZIO_WAIT_READY]++; + pio->io_children[zio->io_child_type][ZIO_WAIT_DONE]++; + mutex_exit(&pio->io_lock); + zio_reexecute(zio); + } + + /* + * Now that all children have been reexecuted, execute the parent. + */ + zio_execute(pio); } -static int -zio_issue_async(zio_t *zio) +void +zio_suspend(spa_t *spa, zio_t *zio) { - (void) taskq_dispatch(zio->io_spa->spa_zio_issue_taskq[zio->io_type], - (task_func_t *)zio_execute, zio, TQ_SLEEP); + if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_PANIC) + fm_panic("Pool '%s' has encountered an uncorrectable I/O " + "failure and the failure mode property for this pool " + "is set to panic.", spa_name(spa)); - return (ZIO_PIPELINE_STOP); + zfs_ereport_post(FM_EREPORT_ZFS_IO_FAILURE, spa, NULL, NULL, 0, 0); + + mutex_enter(&spa->spa_suspend_lock); + + if (spa->spa_suspend_zio_root == NULL) + spa->spa_suspend_zio_root = zio_root(spa, NULL, NULL, 0); + + spa->spa_suspended = B_TRUE; + + if (zio != NULL) { + ASSERT(zio != spa->spa_suspend_zio_root); + ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL); + ASSERT(zio->io_parent == NULL); + ASSERT(zio->io_stage == ZIO_STAGE_DONE); + zio_add_child(spa->spa_suspend_zio_root, zio); + } + + mutex_exit(&spa->spa_suspend_lock); +} + +void +zio_resume(spa_t *spa) +{ + zio_t *pio, *zio; + + /* + * Reexecute all previously suspended i/o. + */ + mutex_enter(&spa->spa_suspend_lock); + spa->spa_suspended = B_FALSE; + cv_broadcast(&spa->spa_suspend_cv); + pio = spa->spa_suspend_zio_root; + spa->spa_suspend_zio_root = NULL; + mutex_exit(&spa->spa_suspend_lock); + + if (pio == NULL) + return; + + while ((zio = pio->io_child) != NULL) { + zio_remove_child(pio, zio); + zio->io_parent = NULL; + zio_reexecute(zio); + } + + ASSERT(pio->io_children[ZIO_CHILD_LOGICAL][ZIO_WAIT_DONE] == 0); + + (void) zio_wait(pio); +} + +void +zio_resume_wait(spa_t *spa) +{ + mutex_enter(&spa->spa_suspend_lock); + while (spa_suspended(spa)) + cv_wait(&spa->spa_suspend_cv, &spa->spa_suspend_lock); + mutex_exit(&spa->spa_suspend_lock); } /* * ========================================================================== - * I/O pipeline interlocks: parent/child dependency scoreboarding + * Gang blocks. + * + * A gang block is a collection of small blocks that looks to the DMU + * like one large block. When zio_dva_allocate() cannot find a block + * of the requested size, due to either severe fragmentation or the pool + * being nearly full, it calls zio_write_gang_block() to construct the + * block from smaller fragments. + * + * A gang block consists of a gang header (zio_gbh_phys_t) and up to + * three (SPA_GBH_NBLKPTRS) gang members. The gang header is just like + * an indirect block: it's an array of block pointers. It consumes + * only one sector and hence is allocatable regardless of fragmentation. + * The gang header's bps point to its gang members, which hold the data. + * + * Gang blocks are self-checksumming, using the bp's + * as the verifier to ensure uniqueness of the SHA256 checksum. + * Critically, the gang block bp's blk_cksum is the checksum of the data, + * not the gang header. This ensures that data block signatures (needed for + * deduplication) are independent of how the block is physically stored. + * + * Gang blocks can be nested: a gang member may itself be a gang block. + * Thus every gang block is a tree in which root and all interior nodes are + * gang headers, and the leaves are normal blocks that contain user data. + * The root of the gang tree is called the gang leader. + * + * To perform any operation (read, rewrite, free, claim) on a gang block, + * zio_gang_assemble() first assembles the gang tree (minus data leaves) + * in the io_gang_tree field of the original logical i/o by recursively + * reading the gang leader and all gang headers below it. This yields + * an in-core tree containing the contents of every gang header and the + * bps for every constituent of the gang block. + * + * With the gang tree now assembled, zio_gang_issue() just walks the gang tree + * and invokes a callback on each bp. To free a gang block, zio_gang_issue() + * calls zio_free_gang() -- a trivial wrapper around zio_free() -- for each bp. + * zio_claim_gang() provides a similarly trivial wrapper for zio_claim(). + * zio_read_gang() is a wrapper around zio_read() that omits reading gang + * headers, since we already have those in io_gang_tree. zio_rewrite_gang() + * performs a zio_rewrite() of the data or, for gang headers, a zio_rewrite() + * of the gang header plus zio_checksum_compute() of the data to update the + * gang header's blk_cksum as described above. + * + * The two-phase assemble/issue model solves the problem of partial failure -- + * what if you'd freed part of a gang block but then couldn't read the + * gang header for another part? Assembling the entire gang tree first + * ensures that all the necessary gang header I/O has succeeded before + * starting the actual work of free, claim, or write. Once the gang tree + * is assembled, free and claim are in-memory operations that cannot fail. + * + * In the event that a gang write fails, zio_dva_unallocate() walks the + * gang tree to immediately free (i.e. insert back into the space map) + * everything we've allocated. This ensures that we don't get ENOSPC + * errors during repeated suspend/resume cycles due to a flaky device. + * + * Gang rewrites only happen during sync-to-convergence. If we can't assemble + * the gang tree, we won't modify the block, so we can safely defer the free + * (knowing that the block is still intact). If we *can* assemble the gang + * tree, then even if some of the rewrites fail, zio_dva_unallocate() will free + * each constituent bp and we can allocate a new block on the next sync pass. + * + * In all cases, the gang tree allows complete recovery from partial failure. * ========================================================================== */ -static int -zio_wait_for_children(zio_t *zio, uint32_t stage, uint64_t *countp) + +static zio_t * +zio_read_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, void *data) { - int rv = ZIO_PIPELINE_CONTINUE; + if (gn != NULL) + return (pio); - mutex_enter(&zio->io_lock); - ASSERT(zio->io_stalled == 0); - if (*countp != 0) { - zio->io_stalled = stage; - rv = ZIO_PIPELINE_STOP; - } - mutex_exit(&zio->io_lock); - - return (rv); + return (zio_read(pio, pio->io_spa, bp, data, BP_GET_PSIZE(bp), + NULL, NULL, pio->io_priority, ZIO_GANG_CHILD_FLAGS(pio), + &pio->io_bookmark)); } -static void -zio_notify_parent(zio_t *zio, uint32_t stage, uint64_t *countp) -{ - zio_t *pio = zio->io_parent; - - mutex_enter(&pio->io_lock); - if (pio->io_error == 0 && !(zio->io_flags & ZIO_FLAG_DONT_PROPAGATE)) - pio->io_error = zio->io_error; - ASSERT3U(*countp, >, 0); - if (--*countp == 0 && pio->io_stalled == stage) { - pio->io_stalled = 0; - mutex_exit(&pio->io_lock); - zio_execute(pio); - } else { - mutex_exit(&pio->io_lock); - } -} - -int -zio_wait_for_children_ready(zio_t *zio) -{ - return (zio_wait_for_children(zio, ZIO_STAGE_WAIT_FOR_CHILDREN_READY, - &zio->io_children_notready)); -} - -int -zio_wait_for_children_done(zio_t *zio) -{ - return (zio_wait_for_children(zio, ZIO_STAGE_WAIT_FOR_CHILDREN_DONE, - &zio->io_children_notdone)); -} - -static int -zio_read_init(zio_t *zio) -{ - blkptr_t *bp = zio->io_bp; - - if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF) { - uint64_t csize = BP_GET_PSIZE(bp); - void *cbuf = zio_buf_alloc(csize); - - zio_push_transform(zio, cbuf, csize, csize); - zio->io_pipeline |= 1U << ZIO_STAGE_READ_DECOMPRESS; - } - - if (BP_IS_GANG(bp)) { - uint64_t gsize = SPA_GANGBLOCKSIZE; - void *gbuf = zio_buf_alloc(gsize); - - zio_push_transform(zio, gbuf, gsize, gsize); - zio->io_pipeline |= 1U << ZIO_STAGE_READ_GANG_MEMBERS; - } - - if (!dmu_ot[BP_GET_TYPE(bp)].ot_metadata && BP_GET_LEVEL(bp) == 0) - zio->io_flags |= ZIO_FLAG_DONT_CACHE; - - return (ZIO_PIPELINE_CONTINUE); -} - -static int -zio_ready(zio_t *zio) -{ - zio_t *pio = zio->io_parent; - - if (zio->io_ready) - zio->io_ready(zio); - - if (pio != NULL) - zio_notify_parent(zio, ZIO_STAGE_WAIT_FOR_CHILDREN_READY, - &pio->io_children_notready); - - if (zio->io_bp) - zio->io_bp_copy = *zio->io_bp; - - return (ZIO_PIPELINE_CONTINUE); -} - -static int -zio_vdev_retry_io(zio_t *zio) -{ - zio_t *pio = zio->io_parent; - - /* - * Preserve the failed bp so that the io_ready() callback can - * update the accounting accordingly. The callback will also be - * responsible for freeing the previously allocated block, if one - * exists. - */ - zio->io_bp_orig = *zio->io_bp; - - /* - * We must zero out the old DVA and blk_birth before reallocating - * the bp. - */ - BP_ZERO_DVAS(zio->io_bp); - zio_reset(zio); - - if (pio) { - /* - * Let the parent know that we will - * re-alloc the write (=> new bp info). - */ - mutex_enter(&pio->io_lock); - pio->io_children_notready++; - - /* - * If the parent I/O is still in the open stage, then - * don't bother telling it to retry since it hasn't - * progressed far enough for it to care. - */ - if (pio->io_stage > ZIO_STAGE_OPEN && IO_IS_ALLOCATING(pio)) - pio->io_flags |= ZIO_FLAG_WRITE_RETRY; - - ASSERT(pio->io_stage <= ZIO_STAGE_WAIT_FOR_CHILDREN_DONE); - mutex_exit(&pio->io_lock); - } - - /* - * We are getting ready to process the retry request so clear - * the flag and the zio's current error status. - */ - zio->io_flags &= ~ZIO_FLAG_WRITE_RETRY; - zio->io_error = 0; - - return (ZIO_PIPELINE_CONTINUE); -} - -int -zio_vdev_resume_io(spa_t *spa) +zio_t * +zio_rewrite_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, void *data) { zio_t *zio; - mutex_enter(&spa->spa_zio_lock); - - /* - * Probe all of vdevs that have experienced an I/O error. - * If we are still unable to verify the integrity of the vdev - * then we prevent the resume from proceeeding. - */ - for (zio = list_head(&spa->spa_zio_list); zio != NULL; - zio = list_next(&spa->spa_zio_list, zio)) { - int error = 0; - - /* We only care about I/Os that must succeed */ - if (zio->io_vd == NULL || zio->io_flags & ZIO_FLAG_CANFAIL) - continue; - error = vdev_probe(zio->io_vd); - if (error) { - mutex_exit(&spa->spa_zio_lock); - return (error); - } - } - - /* - * Clear the vdev stats so that I/O can flow. - */ - vdev_clear(spa, NULL, B_FALSE); - - spa->spa_state = POOL_STATE_ACTIVE; - while ((zio = list_head(&spa->spa_zio_list)) != NULL) { - list_remove(&spa->spa_zio_list, zio); - zio->io_error = 0; - + if (gn != NULL) { + zio = zio_rewrite(pio, pio->io_spa, pio->io_txg, bp, + gn->gn_gbh, SPA_GANGBLOCKSIZE, NULL, NULL, pio->io_priority, + ZIO_GANG_CHILD_FLAGS(pio), &pio->io_bookmark); /* - * If we are resuming an allocating I/O then we force it - * to retry and let it resume operation where it left off. - * Otherwise, go back to the ready stage and pick up from - * there. + * As we rewrite each gang header, the pipeline will compute + * a new gang block header checksum for it; but no one will + * compute a new data checksum, so we do that here. The one + * exception is the gang leader: the pipeline already computed + * its data checksum because that stage precedes gang assembly. + * (Presently, nothing actually uses interior data checksums; + * this is just good hygiene.) */ - if (zio_write_retry && IO_IS_ALLOCATING(zio)) { - zio->io_flags |= ZIO_FLAG_WRITE_RETRY; - zio->io_stage--; - } else { - zio->io_stage = ZIO_STAGE_READY; + if (gn != pio->io_logical->io_gang_tree) { + zio_checksum_compute(zio, BP_GET_CHECKSUM(bp), + data, BP_GET_PSIZE(bp)); } - - (void) taskq_dispatch(zio_taskq, (task_func_t *)zio_execute, - zio, TQ_SLEEP); - } - mutex_exit(&spa->spa_zio_lock); - - /* - * Wait for the taskqs to finish and recheck the pool state since - * it's possible that a resumed I/O has failed again. - */ - taskq_wait(zio_taskq); - if (spa_state(spa) == POOL_STATE_IO_FAILURE) - return (EIO); - - mutex_enter(&spa->spa_zio_lock); - cv_broadcast(&spa->spa_zio_cv); - mutex_exit(&spa->spa_zio_lock); - - return (0); -} - -static int -zio_vdev_suspend_io(zio_t *zio) -{ - spa_t *spa = zio->io_spa; - - /* - * We've experienced an unrecoverable failure so - * set the pool state accordingly and queue all - * failed IOs. - */ - spa->spa_state = POOL_STATE_IO_FAILURE; - - mutex_enter(&spa->spa_zio_lock); - list_insert_tail(&spa->spa_zio_list, zio); - -#ifndef _KERNEL - /* Used to notify ztest that the pool has suspended */ - cv_broadcast(&spa->spa_zio_cv); -#endif - mutex_exit(&spa->spa_zio_lock); - - return (ZIO_PIPELINE_STOP); -} - -static int -zio_assess(zio_t *zio) -{ - spa_t *spa = zio->io_spa; - blkptr_t *bp = zio->io_bp; - vdev_t *vd = zio->io_vd; - - ASSERT(zio->io_children_notready == 0); - ASSERT(zio->io_children_notdone == 0); - - if (bp != NULL) { - ASSERT(bp->blk_pad[0] == 0); - ASSERT(bp->blk_pad[1] == 0); - ASSERT(bp->blk_pad[2] == 0); - ASSERT(bcmp(bp, &zio->io_bp_copy, sizeof (blkptr_t)) == 0); - if (zio->io_type == ZIO_TYPE_WRITE && !BP_IS_HOLE(bp) && - !(zio->io_flags & ZIO_FLAG_IO_REPAIR)) { - ASSERT(!BP_SHOULD_BYTESWAP(bp)); - if (zio->io_ndvas != 0) - ASSERT3U(zio->io_ndvas, <=, BP_GET_NDVAS(bp)); - ASSERT(BP_COUNT_GANG(bp) == 0 || - (BP_COUNT_GANG(bp) == BP_GET_NDVAS(bp))); - } - } - - /* - * Some child I/O has indicated that a retry is necessary, so - * we set an error on the I/O and let the logic below do the - * rest. - */ - if (zio->io_flags & ZIO_FLAG_WRITE_RETRY) - zio->io_error = ERESTART; - - if (vd != NULL) - vdev_stat_update(zio); - - if (zio->io_error) { - /* - * If this I/O is attached to a particular vdev, - * generate an error message describing the I/O failure - * at the block level. We ignore these errors if the - * device is currently unavailable. - */ - if (zio->io_error != ECKSUM && vd != NULL && !vdev_is_dead(vd)) - zfs_ereport_post(FM_EREPORT_ZFS_IO, spa, vd, zio, 0, 0); - - if ((zio->io_error == EIO || - !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) && - zio->io_logical == zio) { - /* - * For root I/O requests, tell the SPA to log the error - * appropriately. Also, generate a logical data - * ereport. - */ - spa_log_error(spa, zio); - - zfs_ereport_post(FM_EREPORT_ZFS_DATA, spa, NULL, zio, - 0, 0); - } - - /* - * If we are an allocating I/O then we attempt to reissue - * the I/O on another vdev unless the pool is out of space. - * We handle this condition based on the spa's failmode - * property. - */ - if (zio_write_retry && zio->io_error != ENOSPC && - IO_IS_ALLOCATING(zio)) - return (zio_vdev_retry_io(zio)); - - ASSERT(!(zio->io_flags & ZIO_FLAG_WRITE_RETRY)); - - /* - * For I/O requests that cannot fail, we carry out - * the requested behavior based on the failmode pool - * property. - * - * XXX - Need to differentiate between an ENOSPC as - * a result of vdev failures vs. a full pool. - */ - if (!(zio->io_flags & ZIO_FLAG_CANFAIL)) { - char *blkbuf; - -#ifdef ZFS_DEBUG - blkbuf = kmem_alloc(BP_SPRINTF_LEN, KM_NOSLEEP); - if (blkbuf) { - sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, - bp ? bp : &zio->io_bp_copy); - } - cmn_err(CE_WARN, "ZFS: %s (%s on %s off %llx: zio %p " - "%s): error %d", zio->io_error == ECKSUM ? - "bad checksum" : "I/O failure", - zio_type_name[zio->io_type], - vdev_description(vd), - (u_longlong_t)zio->io_offset, - (void *)zio, blkbuf ? blkbuf : "", zio->io_error); -#endif - - if (spa_get_failmode(spa) == ZIO_FAILURE_MODE_PANIC) { - fm_panic("Pool '%s' has encountered an " - "uncorrectable I/O failure and the " - "failure mode property for this pool " - "is set to panic.", spa_name(spa)); - } - cmn_err(CE_WARN, "Pool '%s' has encountered " - "an uncorrectable I/O error. " - "Manual intervention is required.", spa_name(spa)); - return (zio_vdev_suspend_io(zio)); - } - } - ASSERT(!(zio->io_flags & ZIO_FLAG_WRITE_RETRY)); - ASSERT(zio->io_children_notready == 0); - - return (ZIO_PIPELINE_CONTINUE); -} - -static int -zio_done(zio_t *zio) -{ - zio_t *pio = zio->io_parent; - spa_t *spa = zio->io_spa; - - ASSERT(zio->io_children_notready == 0); - ASSERT(zio->io_children_notdone == 0); - - zio_clear_transform_stack(zio); - - if (zio->io_done) - zio->io_done(zio); - - ASSERT(zio->io_delegate_list == NULL); - ASSERT(zio->io_delegate_next == NULL); - - if (pio != NULL) { - zio_t *next, *prev; - - mutex_enter(&pio->io_lock); - next = zio->io_sibling_next; - prev = zio->io_sibling_prev; - if (next != NULL) - next->io_sibling_prev = prev; - if (prev != NULL) - prev->io_sibling_next = next; - if (pio->io_child == zio) - pio->io_child = next; - mutex_exit(&pio->io_lock); - - zio_notify_parent(zio, ZIO_STAGE_WAIT_FOR_CHILDREN_DONE, - &pio->io_children_notdone); - } - - /* - * Note: this I/O is now done, and will shortly be freed, so there is no - * need to clear this (or any other) flag. - */ - if (zio->io_flags & ZIO_FLAG_CONFIG_GRABBED) - spa_config_exit(spa, zio); - - if (zio->io_waiter != NULL) { - mutex_enter(&zio->io_lock); - ASSERT(zio->io_stage == ZIO_STAGE_DONE); - zio->io_stalled = zio->io_stage; - cv_broadcast(&zio->io_cv); - mutex_exit(&zio->io_lock); } else { - mutex_destroy(&zio->io_lock); - cv_destroy(&zio->io_cv); - kmem_cache_free(zio_cache, zio); + zio = zio_rewrite(pio, pio->io_spa, pio->io_txg, bp, + data, BP_GET_PSIZE(bp), NULL, NULL, pio->io_priority, + ZIO_GANG_CHILD_FLAGS(pio), &pio->io_bookmark); } - return (ZIO_PIPELINE_STOP); + return (zio); } -/* - * ========================================================================== - * Compression support - * ========================================================================== - */ -static int -zio_write_compress(zio_t *zio) +/* ARGSUSED */ +zio_t * +zio_free_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, void *data) { - int compress = zio->io_compress; - blkptr_t *bp = zio->io_bp; - void *cbuf; - uint64_t lsize = zio->io_size; - uint64_t csize = lsize; - uint64_t cbufsize = 0; - int pass; - - if (bp->blk_birth == zio->io_txg) { - /* - * We're rewriting an existing block, which means we're - * working on behalf of spa_sync(). For spa_sync() to - * converge, it must eventually be the case that we don't - * have to allocate new blocks. But compression changes - * the blocksize, which forces a reallocate, and makes - * convergence take longer. Therefore, after the first - * few passes, stop compressing to ensure convergence. - */ - pass = spa_sync_pass(zio->io_spa); - if (pass > zio_sync_pass.zp_dontcompress) - compress = ZIO_COMPRESS_OFF; - } else { - ASSERT(BP_IS_HOLE(bp)); - pass = 1; - } - - if (compress != ZIO_COMPRESS_OFF) - if (!zio_compress_data(compress, zio->io_data, zio->io_size, - &cbuf, &csize, &cbufsize)) - compress = ZIO_COMPRESS_OFF; - - if (compress != ZIO_COMPRESS_OFF && csize != 0) - zio_push_transform(zio, cbuf, csize, cbufsize); - - /* - * The final pass of spa_sync() must be all rewrites, but the first - * few passes offer a trade-off: allocating blocks defers convergence, - * but newly allocated blocks are sequential, so they can be written - * to disk faster. Therefore, we allow the first few passes of - * spa_sync() to reallocate new blocks, but force rewrites after that. - * There should only be a handful of blocks after pass 1 in any case. - */ - if (bp->blk_birth == zio->io_txg && BP_GET_PSIZE(bp) == csize && - pass > zio_sync_pass.zp_rewrite) { - ASSERT(csize != 0); - BP_SET_LSIZE(bp, lsize); - BP_SET_COMPRESS(bp, compress); - zio->io_pipeline = ZIO_REWRITE_PIPELINE(bp); - } else { - if (bp->blk_birth == zio->io_txg) - BP_ZERO(bp); - if (csize == 0) { - BP_ZERO(bp); - zio->io_pipeline = ZIO_WAIT_FOR_CHILDREN_PIPELINE; - } else { - ASSERT3U(BP_GET_NDVAS(bp), ==, 0); - BP_SET_LSIZE(bp, lsize); - BP_SET_PSIZE(bp, csize); - BP_SET_COMPRESS(bp, compress); - } - } - - return (ZIO_PIPELINE_CONTINUE); + return (zio_free(pio, pio->io_spa, pio->io_txg, bp, + NULL, NULL, ZIO_GANG_CHILD_FLAGS(pio))); } -static int -zio_read_decompress(zio_t *zio) +/* ARGSUSED */ +zio_t * +zio_claim_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, void *data) { - blkptr_t *bp = zio->io_bp; - void *data; - uint64_t size; - uint64_t bufsize; - int compress = BP_GET_COMPRESS(bp); - - ASSERT(compress != ZIO_COMPRESS_OFF); - - zio_pop_transform(zio, &data, &size, &bufsize); - - if (zio_decompress_data(compress, data, size, - zio->io_data, zio->io_size)) - zio->io_error = EIO; - - zio_buf_free(data, bufsize); - - return (ZIO_PIPELINE_CONTINUE); + return (zio_claim(pio, pio->io_spa, pio->io_txg, bp, + NULL, NULL, ZIO_GANG_CHILD_FLAGS(pio))); +} + +static zio_gang_issue_func_t *zio_gang_issue_func[ZIO_TYPES] = { + NULL, + zio_read_gang, + zio_rewrite_gang, + zio_free_gang, + zio_claim_gang, + NULL +}; + +static void zio_gang_tree_assemble_done(zio_t *zio); + +static zio_gang_node_t * +zio_gang_node_alloc(zio_gang_node_t **gnpp) +{ + zio_gang_node_t *gn; + + ASSERT(*gnpp == NULL); + + gn = kmem_zalloc(sizeof (*gn), KM_SLEEP); + gn->gn_gbh = zio_buf_alloc(SPA_GANGBLOCKSIZE); + *gnpp = gn; + + return (gn); } -/* - * ========================================================================== - * Gang block support - * ========================================================================== - */ static void -zio_gang_byteswap(zio_t *zio) +zio_gang_node_free(zio_gang_node_t **gnpp) { - ASSERT(zio->io_size == SPA_GANGBLOCKSIZE); + zio_gang_node_t *gn = *gnpp; - if (BP_SHOULD_BYTESWAP(zio->io_bp)) - byteswap_uint64_array(zio->io_data, zio->io_size); + for (int g = 0; g < SPA_GBH_NBLKPTRS; g++) + ASSERT(gn->gn_child[g] == NULL); + + zio_buf_free(gn->gn_gbh, SPA_GANGBLOCKSIZE); + kmem_free(gn, sizeof (*gn)); + *gnpp = NULL; } -static int -zio_get_gang_header(zio_t *zio) +static void +zio_gang_tree_free(zio_gang_node_t **gnpp) { - blkptr_t *bp = zio->io_bp; - uint64_t gsize = SPA_GANGBLOCKSIZE; - void *gbuf = zio_buf_alloc(gsize); + zio_gang_node_t *gn = *gnpp; + if (gn == NULL) + return; + + for (int g = 0; g < SPA_GBH_NBLKPTRS; g++) + zio_gang_tree_free(&gn->gn_child[g]); + + zio_gang_node_free(gnpp); +} + +static void +zio_gang_tree_assemble(zio_t *lio, blkptr_t *bp, zio_gang_node_t **gnpp) +{ + zio_gang_node_t *gn = zio_gang_node_alloc(gnpp); + + ASSERT(lio->io_logical == lio); ASSERT(BP_IS_GANG(bp)); - zio_push_transform(zio, gbuf, gsize, gsize); - - zio_nowait(zio_create(zio, zio->io_spa, bp->blk_birth, bp, gbuf, gsize, - NULL, NULL, ZIO_TYPE_READ, zio->io_priority, - zio->io_flags & ZIO_FLAG_GANG_INHERIT, - ZIO_STAGE_OPEN, ZIO_READ_GANG_PIPELINE)); - - return (zio_wait_for_children_done(zio)); + zio_nowait(zio_read(lio, lio->io_spa, bp, gn->gn_gbh, + SPA_GANGBLOCKSIZE, zio_gang_tree_assemble_done, gn, + lio->io_priority, ZIO_GANG_CHILD_FLAGS(lio), &lio->io_bookmark)); } -static int -zio_read_gang_members(zio_t *zio) +static void +zio_gang_tree_assemble_done(zio_t *zio) { - zio_gbh_phys_t *gbh; - uint64_t gsize, gbufsize, loff, lsize; - int i; + zio_t *lio = zio->io_logical; + zio_gang_node_t *gn = zio->io_private; + blkptr_t *bp = zio->io_bp; - ASSERT(BP_IS_GANG(zio->io_bp)); + ASSERT(zio->io_parent == lio); + ASSERT(zio->io_child == NULL); - zio_gang_byteswap(zio); - zio_pop_transform(zio, (void **)&gbh, &gsize, &gbufsize); + if (zio->io_error) + return; - for (loff = 0, i = 0; loff != zio->io_size; loff += lsize, i++) { - blkptr_t *gbp = &gbh->zg_blkptr[i]; - lsize = BP_GET_PSIZE(gbp); + if (BP_SHOULD_BYTESWAP(bp)) + byteswap_uint64_array(zio->io_data, zio->io_size); - ASSERT(BP_GET_COMPRESS(gbp) == ZIO_COMPRESS_OFF); - ASSERT3U(lsize, ==, BP_GET_LSIZE(gbp)); - ASSERT3U(loff + lsize, <=, zio->io_size); - ASSERT(i < SPA_GBH_NBLKPTRS); - ASSERT(!BP_IS_HOLE(gbp)); + ASSERT(zio->io_data == gn->gn_gbh); + ASSERT(zio->io_size == SPA_GANGBLOCKSIZE); + ASSERT(gn->gn_gbh->zg_tail.zbt_magic == ZBT_MAGIC); - zio_nowait(zio_read(zio, zio->io_spa, gbp, - (char *)zio->io_data + loff, lsize, - NULL, NULL, zio->io_priority, - zio->io_flags & ZIO_FLAG_GANG_INHERIT, &zio->io_bookmark)); - } - - zio_buf_free(gbh, gbufsize); - - return (zio_wait_for_children_done(zio)); -} - -static int -zio_rewrite_gang_members(zio_t *zio) -{ - zio_gbh_phys_t *gbh; - uint64_t gsize, gbufsize, loff, lsize; - int i; - - ASSERT(BP_IS_GANG(zio->io_bp)); - ASSERT3U(zio->io_size, ==, SPA_GANGBLOCKSIZE); - - zio_gang_byteswap(zio); - zio_pop_transform(zio, (void **)&gbh, &gsize, &gbufsize); - - ASSERT(gsize == gbufsize); - - for (loff = 0, i = 0; loff != zio->io_size; loff += lsize, i++) { - blkptr_t *gbp = &gbh->zg_blkptr[i]; - lsize = BP_GET_PSIZE(gbp); - - ASSERT(BP_GET_COMPRESS(gbp) == ZIO_COMPRESS_OFF); - ASSERT3U(lsize, ==, BP_GET_LSIZE(gbp)); - ASSERT3U(loff + lsize, <=, zio->io_size); - ASSERT(i < SPA_GBH_NBLKPTRS); - ASSERT(!BP_IS_HOLE(gbp)); - - zio_nowait(zio_rewrite(zio, zio->io_spa, zio->io_checksum, - zio->io_txg, gbp, (char *)zio->io_data + loff, lsize, - NULL, NULL, zio->io_priority, - zio->io_flags & ZIO_FLAG_GANG_INHERIT, &zio->io_bookmark)); - } - - zio_push_transform(zio, gbh, gsize, gbufsize); - - return (zio_wait_for_children_ready(zio)); -} - -static int -zio_free_gang_members(zio_t *zio) -{ - zio_gbh_phys_t *gbh; - uint64_t gsize, gbufsize; - int i; - - ASSERT(BP_IS_GANG(zio->io_bp)); - - zio_gang_byteswap(zio); - zio_pop_transform(zio, (void **)&gbh, &gsize, &gbufsize); - - for (i = 0; i < SPA_GBH_NBLKPTRS; i++) { - blkptr_t *gbp = &gbh->zg_blkptr[i]; - - if (BP_IS_HOLE(gbp)) + for (int g = 0; g < SPA_GBH_NBLKPTRS; g++) { + blkptr_t *gbp = &gn->gn_gbh->zg_blkptr[g]; + if (!BP_IS_GANG(gbp)) continue; - zio_nowait(zio_free(zio, zio->io_spa, zio->io_txg, - gbp, NULL, NULL)); + zio_gang_tree_assemble(lio, gbp, &gn->gn_child[g]); + } +} + +static void +zio_gang_tree_issue(zio_t *pio, zio_gang_node_t *gn, blkptr_t *bp, void *data) +{ + zio_t *lio = pio->io_logical; + zio_t *zio; + + ASSERT(BP_IS_GANG(bp) == !!gn); + ASSERT(BP_GET_CHECKSUM(bp) == BP_GET_CHECKSUM(lio->io_bp)); + ASSERT(BP_GET_LSIZE(bp) == BP_GET_PSIZE(bp) || gn == lio->io_gang_tree); + + /* + * If you're a gang header, your data is in gn->gn_gbh. + * If you're a gang member, your data is in 'data' and gn == NULL. + */ + zio = zio_gang_issue_func[lio->io_type](pio, bp, gn, data); + + if (gn != NULL) { + ASSERT(gn->gn_gbh->zg_tail.zbt_magic == ZBT_MAGIC); + + for (int g = 0; g < SPA_GBH_NBLKPTRS; g++) { + blkptr_t *gbp = &gn->gn_gbh->zg_blkptr[g]; + if (BP_IS_HOLE(gbp)) + continue; + zio_gang_tree_issue(zio, gn->gn_child[g], gbp, data); + data = (char *)data + BP_GET_PSIZE(gbp); + } } - zio_buf_free(gbh, gbufsize); + if (gn == lio->io_gang_tree) + ASSERT3P((char *)lio->io_data + lio->io_size, ==, data); + + if (zio != pio) + zio_nowait(zio); +} + +static int +zio_gang_assemble(zio_t *zio) +{ + blkptr_t *bp = zio->io_bp; + + ASSERT(BP_IS_GANG(bp) && zio == zio->io_logical); + + zio_gang_tree_assemble(zio, bp, &zio->io_gang_tree); return (ZIO_PIPELINE_CONTINUE); } static int -zio_claim_gang_members(zio_t *zio) +zio_gang_issue(zio_t *zio) { - zio_gbh_phys_t *gbh; - uint64_t gsize, gbufsize; - int i; + zio_t *lio = zio->io_logical; + blkptr_t *bp = zio->io_bp; - ASSERT(BP_IS_GANG(zio->io_bp)); + if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_DONE)) + return (ZIO_PIPELINE_STOP); - zio_gang_byteswap(zio); - zio_pop_transform(zio, (void **)&gbh, &gsize, &gbufsize); + ASSERT(BP_IS_GANG(bp) && zio == lio); - for (i = 0; i < SPA_GBH_NBLKPTRS; i++) { - blkptr_t *gbp = &gbh->zg_blkptr[i]; - if (BP_IS_HOLE(gbp)) - continue; - zio_nowait(zio_claim(zio, zio->io_spa, zio->io_txg, - gbp, NULL, NULL)); - } + if (zio->io_child_error[ZIO_CHILD_GANG] == 0) + zio_gang_tree_issue(lio, lio->io_gang_tree, bp, lio->io_data); + else + zio_gang_tree_free(&lio->io_gang_tree); - zio_buf_free(gbh, gbufsize); + zio->io_pipeline = ZIO_INTERLOCK_PIPELINE; return (ZIO_PIPELINE_CONTINUE); } static void -zio_write_allocate_gang_member_done(zio_t *zio) +zio_write_gang_member_ready(zio_t *zio) { zio_t *pio = zio->io_parent; + zio_t *lio = zio->io_logical; dva_t *cdva = zio->io_bp->blk_dva; dva_t *pdva = pio->io_bp->blk_dva; uint64_t asize; - int d; - ASSERT3U(pio->io_ndvas, ==, zio->io_ndvas); + if (BP_IS_HOLE(zio->io_bp)) + return; + + ASSERT(BP_IS_HOLE(&zio->io_bp_orig)); + + ASSERT(zio->io_child_type == ZIO_CHILD_GANG); + ASSERT3U(zio->io_prop.zp_ndvas, ==, lio->io_prop.zp_ndvas); + ASSERT3U(zio->io_prop.zp_ndvas, <=, BP_GET_NDVAS(zio->io_bp)); + ASSERT3U(pio->io_prop.zp_ndvas, <=, BP_GET_NDVAS(pio->io_bp)); ASSERT3U(BP_GET_NDVAS(zio->io_bp), <=, BP_GET_NDVAS(pio->io_bp)); - ASSERT3U(zio->io_ndvas, <=, BP_GET_NDVAS(zio->io_bp)); - ASSERT3U(pio->io_ndvas, <=, BP_GET_NDVAS(pio->io_bp)); mutex_enter(&pio->io_lock); - for (d = 0; d < BP_GET_NDVAS(pio->io_bp); d++) { + for (int d = 0; d < BP_GET_NDVAS(zio->io_bp); d++) { ASSERT(DVA_GET_GANG(&pdva[d])); asize = DVA_GET_ASIZE(&pdva[d]); asize += DVA_GET_ASIZE(&cdva[d]); @@ -1529,100 +1472,76 @@ zio_write_allocate_gang_member_done(zio_t *zio) } static int -zio_write_allocate_gang_members(zio_t *zio, metaslab_class_t *mc) +zio_write_gang_block(zio_t *pio) { - blkptr_t *bp = zio->io_bp; - dva_t *dva = bp->blk_dva; - spa_t *spa = zio->io_spa; + spa_t *spa = pio->io_spa; + blkptr_t *bp = pio->io_bp; + zio_t *lio = pio->io_logical; + zio_t *zio; + zio_gang_node_t *gn, **gnpp; zio_gbh_phys_t *gbh; - uint64_t txg = zio->io_txg; - uint64_t resid = zio->io_size; - uint64_t maxalloc = P2ROUNDUP(zio->io_size >> 1, SPA_MINBLOCKSIZE); - uint64_t gsize, loff, lsize; - uint32_t gbps_left; - int ndvas = zio->io_ndvas; + uint64_t txg = pio->io_txg; + uint64_t resid = pio->io_size; + uint64_t lsize; + int ndvas = lio->io_prop.zp_ndvas; int gbh_ndvas = MIN(ndvas + 1, spa_max_replication(spa)); + zio_prop_t zp; int error; - int i, d; - gsize = SPA_GANGBLOCKSIZE; - gbps_left = SPA_GBH_NBLKPTRS; - - error = metaslab_alloc(spa, mc, gsize, bp, gbh_ndvas, txg, NULL, - B_FALSE); + error = metaslab_alloc(spa, spa->spa_normal_class, SPA_GANGBLOCKSIZE, + bp, gbh_ndvas, txg, pio == lio ? NULL : lio->io_bp, + METASLAB_HINTBP_FAVOR | METASLAB_GANG_HEADER); if (error) { - zio->io_error = error; + pio->io_error = error; return (ZIO_PIPELINE_CONTINUE); } - for (d = 0; d < gbh_ndvas; d++) - DVA_SET_GANG(&dva[d], 1); - - bp->blk_birth = txg; - - gbh = zio_buf_alloc(gsize); - bzero(gbh, gsize); - - for (loff = 0, i = 0; loff != zio->io_size; - loff += lsize, resid -= lsize, gbps_left--, i++) { - blkptr_t *gbp = &gbh->zg_blkptr[i]; - dva = gbp->blk_dva; - - ASSERT(gbps_left != 0); - maxalloc = MIN(maxalloc, resid); - - while (resid <= maxalloc * gbps_left) { - error = metaslab_alloc(spa, mc, maxalloc, gbp, ndvas, - txg, bp, B_FALSE); - if (error == 0) - break; - ASSERT3U(error, ==, ENOSPC); - /* XXX - free up previous allocations? */ - if (maxalloc == SPA_MINBLOCKSIZE) { - zio->io_error = error; - return (ZIO_PIPELINE_CONTINUE); - } - maxalloc = P2ROUNDUP(maxalloc >> 1, SPA_MINBLOCKSIZE); - } - - if (resid <= maxalloc * gbps_left) { - lsize = maxalloc; - BP_SET_LSIZE(gbp, lsize); - BP_SET_PSIZE(gbp, lsize); - BP_SET_COMPRESS(gbp, ZIO_COMPRESS_OFF); - gbp->blk_birth = txg; - zio_nowait(zio_rewrite(zio, spa, - zio->io_checksum, txg, gbp, - (char *)zio->io_data + loff, lsize, - zio_write_allocate_gang_member_done, NULL, - zio->io_priority, - zio->io_flags & ZIO_FLAG_GANG_INHERIT, - &zio->io_bookmark)); - } else { - lsize = P2ROUNDUP(resid / gbps_left, SPA_MINBLOCKSIZE); - ASSERT(lsize != SPA_MINBLOCKSIZE); - zio_nowait(zio_write_allocate(zio, spa, - zio->io_checksum, txg, gbp, - (char *)zio->io_data + loff, lsize, - zio_write_allocate_gang_member_done, NULL, - zio->io_priority, - zio->io_flags & ZIO_FLAG_GANG_INHERIT)); - } + if (pio == lio) { + gnpp = &lio->io_gang_tree; + } else { + gnpp = pio->io_private; + ASSERT(pio->io_ready == zio_write_gang_member_ready); } - ASSERT(resid == 0 && loff == zio->io_size); - - zio->io_pipeline |= 1U << ZIO_STAGE_GANG_CHECKSUM_GENERATE; - - zio_push_transform(zio, gbh, gsize, gsize); + gn = zio_gang_node_alloc(gnpp); + gbh = gn->gn_gbh; + bzero(gbh, SPA_GANGBLOCKSIZE); /* - * As much as we'd like this to be 'ready' instead of 'done', - * updating our ASIZE doesn't happen until the io_done callback, - * so we have to wait for that to finish in order for our BP - * to be stable. + * Create the gang header. */ - return (zio_wait_for_children_done(zio)); + zio = zio_rewrite(pio, spa, txg, bp, gbh, SPA_GANGBLOCKSIZE, NULL, NULL, + pio->io_priority, ZIO_GANG_CHILD_FLAGS(pio), &pio->io_bookmark); + + /* + * Create and nowait the gang children. + */ + for (int g = 0; resid != 0; resid -= lsize, g++) { + lsize = P2ROUNDUP(resid / (SPA_GBH_NBLKPTRS - g), + SPA_MINBLOCKSIZE); + ASSERT(lsize >= SPA_MINBLOCKSIZE && lsize <= resid); + + zp.zp_checksum = lio->io_prop.zp_checksum; + zp.zp_compress = ZIO_COMPRESS_OFF; + zp.zp_type = DMU_OT_NONE; + zp.zp_level = 0; + zp.zp_ndvas = lio->io_prop.zp_ndvas; + + zio_nowait(zio_write(zio, spa, txg, &gbh->zg_blkptr[g], + (char *)pio->io_data + (pio->io_size - resid), lsize, &zp, + zio_write_gang_member_ready, NULL, &gn->gn_child[g], + pio->io_priority, ZIO_GANG_CHILD_FLAGS(pio), + &pio->io_bookmark)); + } + + /* + * Set pio's pipeline to just wait for zio to finish. + */ + pio->io_pipeline = ZIO_INTERLOCK_PIPELINE; + + zio_nowait(zio); + + return (ZIO_PIPELINE_CONTINUE); } /* @@ -1630,6 +1549,7 @@ zio_write_allocate_gang_members(zio_t *zio, metaslab_class_t *mc) * Allocate and free blocks * ========================================================================== */ + static int zio_dva_allocate(zio_t *zio) { @@ -1640,29 +1560,16 @@ zio_dva_allocate(zio_t *zio) ASSERT(BP_IS_HOLE(bp)); ASSERT3U(BP_GET_NDVAS(bp), ==, 0); - ASSERT3U(zio->io_ndvas, >, 0); - ASSERT3U(zio->io_ndvas, <=, spa_max_replication(spa)); - - /* - * For testing purposes, we force I/Os to retry. We don't allow - * retries beyond the first pass since those I/Os are non-allocating - * writes. - */ - if (zio_io_fail_shift && - spa_sync_pass(zio->io_spa) <= zio_sync_pass.zp_rewrite && - zio_io_should_fail(zio_io_fail_shift)) - zio->io_flags |= ZIO_FLAG_WRITE_RETRY; - + ASSERT3U(zio->io_prop.zp_ndvas, >, 0); + ASSERT3U(zio->io_prop.zp_ndvas, <=, spa_max_replication(spa)); ASSERT3U(zio->io_size, ==, BP_GET_PSIZE(bp)); - error = metaslab_alloc(spa, mc, zio->io_size, bp, zio->io_ndvas, - zio->io_txg, NULL, B_FALSE); + error = metaslab_alloc(spa, mc, zio->io_size, bp, + zio->io_prop.zp_ndvas, zio->io_txg, NULL, 0); - if (error == 0) { - bp->blk_birth = zio->io_txg; - } else if (error == ENOSPC && zio->io_size > SPA_MINBLOCKSIZE) { - return (zio_write_allocate_gang_members(zio, mc)); - } else { + if (error) { + if (error == ENOSPC && zio->io_size > SPA_MINBLOCKSIZE) + return (zio_write_gang_block(zio)); zio->io_error = error; } @@ -1672,11 +1579,7 @@ zio_dva_allocate(zio_t *zio) static int zio_dva_free(zio_t *zio) { - blkptr_t *bp = zio->io_bp; - - metaslab_free(zio->io_spa, bp, zio->io_txg, B_FALSE); - - BP_ZERO(bp); + metaslab_free(zio->io_spa, zio->io_bp, zio->io_txg, B_FALSE); return (ZIO_PIPELINE_CONTINUE); } @@ -1684,142 +1587,326 @@ zio_dva_free(zio_t *zio) static int zio_dva_claim(zio_t *zio) { - zio->io_error = metaslab_claim(zio->io_spa, zio->io_bp, zio->io_txg); + int error; + + error = metaslab_claim(zio->io_spa, zio->io_bp, zio->io_txg); + if (error) + zio->io_error = error; return (ZIO_PIPELINE_CONTINUE); } +/* + * Undo an allocation. This is used by zio_done() when an I/O fails + * and we want to give back the block we just allocated. + * This handles both normal blocks and gang blocks. + */ +static void +zio_dva_unallocate(zio_t *zio, zio_gang_node_t *gn, blkptr_t *bp) +{ + spa_t *spa = zio->io_spa; + boolean_t now = !(zio->io_flags & ZIO_FLAG_IO_REWRITE); + + ASSERT(bp->blk_birth == zio->io_txg || BP_IS_HOLE(bp)); + + if (zio->io_bp == bp && !now) { + /* + * This is a rewrite for sync-to-convergence. + * We can't do a metaslab_free(NOW) because bp wasn't allocated + * during this sync pass, which means that metaslab_sync() + * already committed the allocation. + */ + ASSERT(DVA_EQUAL(BP_IDENTITY(bp), + BP_IDENTITY(&zio->io_bp_orig))); + ASSERT(spa_sync_pass(spa) > 1); + + if (BP_IS_GANG(bp) && gn == NULL) { + /* + * This is a gang leader whose gang header(s) we + * couldn't read now, so defer the free until later. + * The block should still be intact because without + * the headers, we'd never even start the rewrite. + */ + bplist_enqueue_deferred(&spa->spa_sync_bplist, bp); + return; + } + } + + if (!BP_IS_HOLE(bp)) + metaslab_free(spa, bp, bp->blk_birth, now); + + if (gn != NULL) { + for (int g = 0; g < SPA_GBH_NBLKPTRS; g++) { + zio_dva_unallocate(zio, gn->gn_child[g], + &gn->gn_gbh->zg_blkptr[g]); + } + } +} + +/* + * Try to allocate an intent log block. Return 0 on success, errno on failure. + */ +int +zio_alloc_blk(spa_t *spa, uint64_t size, blkptr_t *new_bp, blkptr_t *old_bp, + uint64_t txg) +{ + int error; + + error = metaslab_alloc(spa, spa->spa_log_class, size, + new_bp, 1, txg, old_bp, METASLAB_HINTBP_AVOID); + + if (error) + error = metaslab_alloc(spa, spa->spa_normal_class, size, + new_bp, 1, txg, old_bp, METASLAB_HINTBP_AVOID); + + if (error == 0) { + BP_SET_LSIZE(new_bp, size); + BP_SET_PSIZE(new_bp, size); + BP_SET_COMPRESS(new_bp, ZIO_COMPRESS_OFF); + BP_SET_CHECKSUM(new_bp, ZIO_CHECKSUM_ZILOG); + BP_SET_TYPE(new_bp, DMU_OT_INTENT_LOG); + BP_SET_LEVEL(new_bp, 0); + BP_SET_BYTEORDER(new_bp, ZFS_HOST_BYTEORDER); + } + + return (error); +} + +/* + * Free an intent log block. We know it can't be a gang block, so there's + * nothing to do except metaslab_free() it. + */ +void +zio_free_blk(spa_t *spa, blkptr_t *bp, uint64_t txg) +{ + ASSERT(!BP_IS_GANG(bp)); + + metaslab_free(spa, bp, txg, B_FALSE); +} + /* * ========================================================================== * Read and write to physical devices * ========================================================================== */ +static void +zio_vdev_io_probe_done(zio_t *zio) +{ + zio_t *dio; + vdev_t *vd = zio->io_private; + + mutex_enter(&vd->vdev_probe_lock); + ASSERT(vd->vdev_probe_zio == zio); + vd->vdev_probe_zio = NULL; + mutex_exit(&vd->vdev_probe_lock); + + while ((dio = zio->io_delegate_list) != NULL) { + zio->io_delegate_list = dio->io_delegate_next; + dio->io_delegate_next = NULL; + if (!vdev_accessible(vd, dio)) + dio->io_error = ENXIO; + zio_execute(dio); + } +} + +/* + * Probe the device to determine whether I/O failure is specific to this + * zio (e.g. a bad sector) or affects the entire vdev (e.g. unplugged). + */ +static int +zio_vdev_io_probe(zio_t *zio) +{ + vdev_t *vd = zio->io_vd; + zio_t *pio = NULL; + boolean_t created_pio = B_FALSE; + + /* + * Don't probe the probe. + */ + if (zio->io_flags & ZIO_FLAG_PROBE) + return (ZIO_PIPELINE_CONTINUE); + + /* + * To prevent 'probe storms' when a device fails, we create + * just one probe i/o at a time. All zios that want to probe + * this vdev will join the probe zio's io_delegate_list. + */ + mutex_enter(&vd->vdev_probe_lock); + + if ((pio = vd->vdev_probe_zio) == NULL) { + vd->vdev_probe_zio = pio = zio_root(zio->io_spa, + zio_vdev_io_probe_done, vd, ZIO_FLAG_CANFAIL); + created_pio = B_TRUE; + vd->vdev_probe_wanted = B_TRUE; + spa_async_request(zio->io_spa, SPA_ASYNC_PROBE); + } + + zio->io_delegate_next = pio->io_delegate_list; + pio->io_delegate_list = zio; + + mutex_exit(&vd->vdev_probe_lock); + + if (created_pio) { + zio_nowait(vdev_probe(vd, pio)); + zio_nowait(pio); + } + + return (ZIO_PIPELINE_STOP); +} + static int zio_vdev_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; - vdev_t *tvd = vd ? vd->vdev_top : NULL; - blkptr_t *bp = zio->io_bp; uint64_t align; spa_t *spa = zio->io_spa; - /* - * If the pool is already in a failure state then just suspend - * this IO until the problem is resolved. We will reissue them - * at that time. - */ - if (spa_state(spa) == POOL_STATE_IO_FAILURE && - zio->io_type == ZIO_TYPE_WRITE) - return (zio_vdev_suspend_io(zio)); + ASSERT(zio->io_error == 0); + ASSERT(zio->io_child_error[ZIO_CHILD_VDEV] == 0); - /* - * The mirror_ops handle multiple DVAs in a single BP - */ - if (vd == NULL) + if (vd == NULL) { + if (!(zio->io_flags & ZIO_FLAG_CONFIG_WRITER)) + spa_config_enter(spa, SCL_ZIO, zio, RW_READER); + + /* + * The mirror_ops handle multiple DVAs in a single BP. + */ return (vdev_mirror_ops.vdev_op_io_start(zio)); - - align = 1ULL << tvd->vdev_ashift; - - if (zio->io_retries == 0 && vd == tvd) - zio->io_flags |= ZIO_FLAG_FAILFAST; - - if (!(zio->io_flags & ZIO_FLAG_PHYSICAL) && vd->vdev_children == 0) { - zio->io_flags |= ZIO_FLAG_PHYSICAL; - zio->io_offset += VDEV_LABEL_START_SIZE; } + align = 1ULL << vd->vdev_top->vdev_ashift; + if (P2PHASE(zio->io_size, align) != 0) { uint64_t asize = P2ROUNDUP(zio->io_size, align); char *abuf = zio_buf_alloc(asize); - ASSERT(vd == tvd); + ASSERT(vd == vd->vdev_top); if (zio->io_type == ZIO_TYPE_WRITE) { bcopy(zio->io_data, abuf, zio->io_size); bzero(abuf + zio->io_size, asize - zio->io_size); } - zio_push_transform(zio, abuf, asize, asize); - ASSERT(!(zio->io_flags & ZIO_FLAG_SUBBLOCK)); - zio->io_flags |= ZIO_FLAG_SUBBLOCK; + zio_push_transform(zio, abuf, asize, asize, zio_subblock); } ASSERT(P2PHASE(zio->io_offset, align) == 0); ASSERT(P2PHASE(zio->io_size, align) == 0); - ASSERT(bp == NULL || - P2ROUNDUP(ZIO_GET_IOSIZE(zio), align) == zio->io_size); ASSERT(zio->io_type != ZIO_TYPE_WRITE || (spa_mode & FWRITE)); + if (vd->vdev_ops->vdev_op_leaf && + (zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE)) { + + if (zio->io_type == ZIO_TYPE_READ && vdev_cache_read(zio) == 0) + return (ZIO_PIPELINE_STOP); + + if ((zio = vdev_queue_io(zio)) == NULL) + return (ZIO_PIPELINE_STOP); + + if (!vdev_accessible(vd, zio)) { + zio->io_error = ENXIO; + zio_interrupt(zio); + return (ZIO_PIPELINE_STOP); + } + + } + return (vd->vdev_ops->vdev_op_io_start(zio)); } static int zio_vdev_io_done(zio_t *zio) -{ - if (zio->io_vd == NULL) - return (vdev_mirror_ops.vdev_op_io_done(zio)); - - return (zio->io_vd->vdev_ops->vdev_op_io_done(zio)); -} - -/* XXPOLICY */ -boolean_t -zio_should_retry(zio_t *zio) { vdev_t *vd = zio->io_vd; + vdev_ops_t *ops = vd ? vd->vdev_ops : &vdev_mirror_ops; + boolean_t unexpected_error = B_FALSE; - if (zio->io_error == 0) - return (B_FALSE); - if (zio->io_delegate_list != NULL) - return (B_FALSE); - if (vd && vd != vd->vdev_top) - return (B_FALSE); - if (zio->io_flags & ZIO_FLAG_DONT_RETRY) - return (B_FALSE); - if (zio->io_retries > 0) - return (B_FALSE); + if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE)) + return (ZIO_PIPELINE_STOP); - return (B_TRUE); + ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); + + if (vd != NULL && vd->vdev_ops->vdev_op_leaf) { + + vdev_queue_io_done(zio); + + if (zio->io_type == ZIO_TYPE_WRITE) + vdev_cache_write(zio); + + if (zio_injection_enabled && zio->io_error == 0) + zio->io_error = zio_handle_device_injection(vd, EIO); + + if (zio_injection_enabled && zio->io_error == 0) + zio->io_error = zio_handle_label_injection(zio, EIO); + + if (zio->io_error) { + if (!vdev_accessible(vd, zio)) { + zio->io_error = ENXIO; + } else { + unexpected_error = B_TRUE; + } + } + } + + ops->vdev_op_io_done(zio); + + if (unexpected_error) + return (zio_vdev_io_probe(zio)); + + return (ZIO_PIPELINE_CONTINUE); } static int zio_vdev_io_assess(zio_t *zio) { vdev_t *vd = zio->io_vd; - vdev_t *tvd = vd ? vd->vdev_top : NULL; - ASSERT(zio->io_vsd == NULL); + if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE)) + return (ZIO_PIPELINE_STOP); - if (zio->io_flags & ZIO_FLAG_SUBBLOCK) { - void *abuf; - uint64_t asize; - ASSERT(vd == tvd); - zio_pop_transform(zio, &abuf, &asize, &asize); - if (zio->io_type == ZIO_TYPE_READ) - bcopy(abuf, zio->io_data, zio->io_size); - zio_buf_free(abuf, asize); - zio->io_flags &= ~ZIO_FLAG_SUBBLOCK; + if (vd == NULL && !(zio->io_flags & ZIO_FLAG_CONFIG_WRITER)) + spa_config_exit(zio->io_spa, SCL_ZIO, zio); + + if (zio->io_vsd != NULL) { + zio->io_vsd_free(zio); + zio->io_vsd = NULL; } - if (zio_injection_enabled && !zio->io_error) + if (zio_injection_enabled && zio->io_error == 0) zio->io_error = zio_handle_fault_injection(zio, EIO); /* * If the I/O failed, determine whether we should attempt to retry it. */ - /* XXPOLICY */ - if (zio_should_retry(zio)) { - ASSERT(tvd == vd); - - zio->io_retries++; + if (zio->io_error && vd == NULL && + !(zio->io_flags & (ZIO_FLAG_DONT_RETRY | ZIO_FLAG_IO_RETRY))) { + ASSERT(!(zio->io_flags & ZIO_FLAG_DONT_QUEUE)); /* not a leaf */ + ASSERT(!(zio->io_flags & ZIO_FLAG_IO_BYPASS)); /* not a leaf */ zio->io_error = 0; - zio->io_flags &= ZIO_FLAG_RETRY_INHERIT; - /* XXPOLICY */ - zio->io_flags &= ~ZIO_FLAG_FAILFAST; - zio->io_flags |= ZIO_FLAG_DONT_CACHE; + zio->io_flags |= ZIO_FLAG_IO_RETRY | + ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_AGGREGATE; zio->io_stage = ZIO_STAGE_VDEV_IO_START - 1; - - return (ZIO_PIPELINE_CONTINUE); + zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE); + return (ZIO_PIPELINE_STOP); } + /* + * If we got an error on a leaf device, convert it to ENXIO + * if the device is not accessible at all. + */ + if (zio->io_error && vd != NULL && vd->vdev_ops->vdev_op_leaf && + !vdev_accessible(vd, zio)) + zio->io_error = ENXIO; + + /* + * If we can't write to an interior vdev (mirror or RAID-Z), + * set vdev_cant_write so that we stop trying to allocate from it. + */ + if (zio->io_error == ENXIO && zio->io_type == ZIO_TYPE_WRITE && + vd != NULL && !vd->vdev_ops->vdev_op_leaf) + vd->vdev_cant_write = B_TRUE; + + if (zio->io_error) + zio->io_pipeline = ZIO_INTERLOCK_PIPELINE; + return (ZIO_PIPELINE_CONTINUE); } @@ -1858,31 +1945,30 @@ zio_vdev_io_bypass(zio_t *zio) static int zio_checksum_generate(zio_t *zio) { - int checksum = zio->io_checksum; blkptr_t *bp = zio->io_bp; + enum zio_checksum checksum; - ASSERT3U(zio->io_size, ==, BP_GET_PSIZE(bp)); + if (bp == NULL) { + /* + * This is zio_write_phys(). + * We're either generating a label checksum, or none at all. + */ + checksum = zio->io_prop.zp_checksum; - BP_SET_CHECKSUM(bp, checksum); - BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER); + if (checksum == ZIO_CHECKSUM_OFF) + return (ZIO_PIPELINE_CONTINUE); - zio_checksum(checksum, &bp->blk_cksum, zio->io_data, zio->io_size); + ASSERT(checksum == ZIO_CHECKSUM_LABEL); + } else { + if (BP_IS_GANG(bp) && zio->io_child_type == ZIO_CHILD_GANG) { + ASSERT(!IO_IS_ALLOCATING(zio)); + checksum = ZIO_CHECKSUM_GANG_HEADER; + } else { + checksum = BP_GET_CHECKSUM(bp); + } + } - return (ZIO_PIPELINE_CONTINUE); -} - -static int -zio_gang_checksum_generate(zio_t *zio) -{ - zio_cksum_t zc; - zio_gbh_phys_t *gbh = zio->io_data; - - ASSERT(BP_IS_GANG(zio->io_bp)); - ASSERT3U(zio->io_size, ==, SPA_GANGBLOCKSIZE); - - zio_set_gang_verifier(zio, &gbh->zg_tail.zbt_cksum); - - zio_checksum(ZIO_CHECKSUM_GANG_HEADER, &zc, zio->io_data, zio->io_size); + zio_checksum_compute(zio, checksum, zio->io_data, zio->io_size); return (ZIO_PIPELINE_CONTINUE); } @@ -1890,11 +1976,26 @@ zio_gang_checksum_generate(zio_t *zio) static int zio_checksum_verify(zio_t *zio) { - if (zio->io_bp != NULL) { - zio->io_error = zio_checksum_error(zio); - if (zio->io_error && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) + blkptr_t *bp = zio->io_bp; + int error; + + if (bp == NULL) { + /* + * This is zio_read_phys(). + * We're either verifying a label checksum, or nothing at all. + */ + if (zio->io_prop.zp_checksum == ZIO_CHECKSUM_OFF) + return (ZIO_PIPELINE_CONTINUE); + + ASSERT(zio->io_prop.zp_checksum == ZIO_CHECKSUM_LABEL); + } + + if ((error = zio_checksum_error(zio)) != 0) { + zio->io_error = error; + if (!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { zfs_ereport_post(FM_EREPORT_ZFS_CHECKSUM, zio->io_spa, zio->io_vd, zio, 0, 0); + } } return (ZIO_PIPELINE_CONTINUE); @@ -1910,173 +2011,263 @@ zio_checksum_verified(zio_t *zio) } /* - * Set the external verifier for a gang block based on stuff in the bp + * ========================================================================== + * Error rank. Error are ranked in the order 0, ENXIO, ECKSUM, EIO, other. + * An error of 0 indictes success. ENXIO indicates whole-device failure, + * which may be transient (e.g. unplugged) or permament. ECKSUM and EIO + * indicate errors that are specific to one I/O, and most likely permanent. + * Any other error is presumed to be worse because we weren't expecting it. + * ========================================================================== */ -void -zio_set_gang_verifier(zio_t *zio, zio_cksum_t *zcp) +int +zio_worst_error(int e1, int e2) { - blkptr_t *bp = zio->io_bp; + static int zio_error_rank[] = { 0, ENXIO, ECKSUM, EIO }; + int r1, r2; - zcp->zc_word[0] = DVA_GET_VDEV(BP_IDENTITY(bp)); - zcp->zc_word[1] = DVA_GET_OFFSET(BP_IDENTITY(bp)); - zcp->zc_word[2] = bp->blk_birth; - zcp->zc_word[3] = 0; + for (r1 = 0; r1 < sizeof (zio_error_rank) / sizeof (int); r1++) + if (e1 == zio_error_rank[r1]) + break; + + for (r2 = 0; r2 < sizeof (zio_error_rank) / sizeof (int); r2++) + if (e2 == zio_error_rank[r2]) + break; + + return (r1 > r2 ? e1 : e2); } /* * ========================================================================== - * Define the pipeline + * I/O completion * ========================================================================== */ -typedef int zio_pipe_stage_t(zio_t *zio); +static int +zio_ready(zio_t *zio) +{ + blkptr_t *bp = zio->io_bp; + zio_t *pio = zio->io_parent; -zio_pipe_stage_t *zio_pipeline[ZIO_STAGE_DONE + 2] = { + if (zio->io_ready) { + if (BP_IS_GANG(bp) && + zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_READY)) + return (ZIO_PIPELINE_STOP); + + ASSERT(IO_IS_ALLOCATING(zio)); + ASSERT(bp->blk_birth == zio->io_txg || BP_IS_HOLE(bp)); + ASSERT(zio->io_children[ZIO_CHILD_GANG][ZIO_WAIT_READY] == 0); + + zio->io_ready(zio); + } + + if (bp != NULL && bp != &zio->io_bp_copy) + zio->io_bp_copy = *bp; + + if (zio->io_error) + zio->io_pipeline = ZIO_INTERLOCK_PIPELINE; + + if (pio != NULL) + zio_notify_parent(pio, zio, ZIO_WAIT_READY); + + return (ZIO_PIPELINE_CONTINUE); +} + +static int +zio_done(zio_t *zio) +{ + spa_t *spa = zio->io_spa; + zio_t *pio = zio->io_parent; + zio_t *lio = zio->io_logical; + blkptr_t *bp = zio->io_bp; + vdev_t *vd = zio->io_vd; + uint64_t psize = zio->io_size; + + /* + * If our of children haven't all completed, + * wait for them and then repeat this pipeline stage. + */ + if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE) || + zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_DONE) || + zio_wait_for_children(zio, ZIO_CHILD_LOGICAL, ZIO_WAIT_DONE)) + return (ZIO_PIPELINE_STOP); + + for (int c = 0; c < ZIO_CHILD_TYPES; c++) + for (int w = 0; w < ZIO_WAIT_TYPES; w++) + ASSERT(zio->io_children[c][w] == 0); + + if (bp != NULL) { + ASSERT(bp->blk_pad[0] == 0); + ASSERT(bp->blk_pad[1] == 0); + ASSERT(bp->blk_pad[2] == 0); + ASSERT(bcmp(bp, &zio->io_bp_copy, sizeof (blkptr_t)) == 0 || + (pio != NULL && bp == pio->io_bp)); + if (zio->io_type == ZIO_TYPE_WRITE && !BP_IS_HOLE(bp) && + !(zio->io_flags & ZIO_FLAG_IO_REPAIR)) { + ASSERT(!BP_SHOULD_BYTESWAP(bp)); + ASSERT3U(zio->io_prop.zp_ndvas, <=, BP_GET_NDVAS(bp)); + ASSERT(BP_COUNT_GANG(bp) == 0 || + (BP_COUNT_GANG(bp) == BP_GET_NDVAS(bp))); + } + } + + /* + * If there were child vdev or gang errors, they apply to us now. + */ + zio_inherit_child_errors(zio, ZIO_CHILD_VDEV); + zio_inherit_child_errors(zio, ZIO_CHILD_GANG); + + zio_pop_transforms(zio); /* note: may set zio->io_error */ + + vdev_stat_update(zio, psize); + + if (zio->io_error) { + /* + * If this I/O is attached to a particular vdev, + * generate an error message describing the I/O failure + * at the block level. We ignore these errors if the + * device is currently unavailable. + */ + if (zio->io_error != ECKSUM && vd != NULL && !vdev_is_dead(vd)) + zfs_ereport_post(FM_EREPORT_ZFS_IO, spa, vd, zio, 0, 0); + + if ((zio->io_error == EIO || + !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) && zio == lio) { + /* + * For logical I/O requests, tell the SPA to log the + * error and generate a logical data ereport. + */ + spa_log_error(spa, zio); + zfs_ereport_post(FM_EREPORT_ZFS_DATA, spa, NULL, zio, + 0, 0); + } + } + + if (zio->io_error && zio == lio) { + /* + * Determine whether zio should be reexecuted. This will + * propagate all the way to the root via zio_notify_parent(). + */ + ASSERT(vd == NULL && bp != NULL); + + if (IO_IS_ALLOCATING(zio)) + if (zio->io_error != ENOSPC) + zio->io_reexecute |= ZIO_REEXECUTE_NOW; + else + zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND; + + if ((zio->io_type == ZIO_TYPE_READ || + zio->io_type == ZIO_TYPE_FREE) && + zio->io_error == ENXIO && + spa_get_failmode(spa) != ZIO_FAILURE_MODE_CONTINUE) + zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND; + + if (!(zio->io_flags & ZIO_FLAG_CANFAIL) && !zio->io_reexecute) + zio->io_reexecute |= ZIO_REEXECUTE_SUSPEND; + } + + /* + * If there were logical child errors, they apply to us now. + * We defer this until now to avoid conflating logical child + * errors with errors that happened to the zio itself when + * updating vdev stats and reporting FMA events above. + */ + zio_inherit_child_errors(zio, ZIO_CHILD_LOGICAL); + + if (zio->io_reexecute) { + /* + * This is a logical I/O that wants to reexecute. + * + * Reexecute is top-down. When an i/o fails, if it's not + * the root, it simply notifies its parent and sticks around. + * The parent, seeing that it still has children in zio_done(), + * does the same. This percolates all the way up to the root. + * The root i/o will reexecute or suspend the entire tree. + * + * This approach ensures that zio_reexecute() honors + * all the original i/o dependency relationships, e.g. + * parents not executing until children are ready. + */ + ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL); + + if (IO_IS_ALLOCATING(zio)) + zio_dva_unallocate(zio, zio->io_gang_tree, bp); + + zio_gang_tree_free(&zio->io_gang_tree); + + if (pio != NULL) { + /* + * We're not a root i/o, so there's nothing to do + * but notify our parent. Don't propagate errors + * upward since we haven't permanently failed yet. + */ + zio->io_flags |= ZIO_FLAG_DONT_PROPAGATE; + zio_notify_parent(pio, zio, ZIO_WAIT_DONE); + } else if (zio->io_reexecute & ZIO_REEXECUTE_SUSPEND) { + /* + * We'd fail again if we reexecuted now, so suspend + * until conditions improve (e.g. device comes online). + */ + zio_suspend(spa, zio); + } else { + /* + * Reexecution is potentially a huge amount of work. + * Hand it off to the otherwise-unused claim taskq. + */ + (void) taskq_dispatch( + spa->spa_zio_taskq[ZIO_TYPE_CLAIM][ZIO_TASKQ_ISSUE], + (task_func_t *)zio_reexecute, zio, TQ_SLEEP); + } + return (ZIO_PIPELINE_STOP); + } + + ASSERT(zio->io_child == NULL); + ASSERT(zio->io_reexecute == 0); + ASSERT(zio->io_error == 0 || (zio->io_flags & ZIO_FLAG_CANFAIL)); + + if (zio->io_done) + zio->io_done(zio); + + zio_gang_tree_free(&zio->io_gang_tree); + + ASSERT(zio->io_delegate_list == NULL); + ASSERT(zio->io_delegate_next == NULL); + + if (pio != NULL) { + zio_remove_child(pio, zio); + zio_notify_parent(pio, zio, ZIO_WAIT_DONE); + } + + if (zio->io_waiter != NULL) { + mutex_enter(&zio->io_lock); + zio->io_executor = NULL; + cv_broadcast(&zio->io_cv); + mutex_exit(&zio->io_lock); + } else { + zio_destroy(zio); + } + + return (ZIO_PIPELINE_STOP); +} + +/* + * ========================================================================== + * I/O pipeline definition + * ========================================================================== + */ +static zio_pipe_stage_t *zio_pipeline[ZIO_STAGES] = { NULL, - zio_wait_for_children_ready, - zio_read_init, zio_issue_async, - zio_write_compress, + zio_read_bp_init, + zio_write_bp_init, zio_checksum_generate, - zio_get_gang_header, - zio_rewrite_gang_members, - zio_free_gang_members, - zio_claim_gang_members, + zio_gang_assemble, + zio_gang_issue, zio_dva_allocate, zio_dva_free, zio_dva_claim, - zio_gang_checksum_generate, zio_ready, zio_vdev_io_start, zio_vdev_io_done, zio_vdev_io_assess, - zio_wait_for_children_done, zio_checksum_verify, - zio_read_gang_members, - zio_read_decompress, - zio_assess, - zio_done, - NULL + zio_done }; - -/* - * Execute the I/O pipeline until one of the following occurs: - * (1) the I/O completes; (2) the pipeline stalls waiting for - * dependent child I/Os; (3) the I/O issues, so we're waiting - * for an I/O completion interrupt; (4) the I/O is delegated by - * vdev-level caching or aggregation; (5) the I/O is deferred - * due to vdev-level queueing; (6) the I/O is handed off to - * another thread. In all cases, the pipeline stops whenever - * there's no CPU work; it never burns a thread in cv_wait(). - * - * There's no locking on io_stage because there's no legitimate way - * for multiple threads to be attempting to process the same I/O. - */ -void -zio_execute(zio_t *zio) -{ - while (zio->io_stage < ZIO_STAGE_DONE) { - uint32_t pipeline = zio->io_pipeline; - int rv; - - ASSERT(!MUTEX_HELD(&zio->io_lock)); - - /* - * If an error occurred outside the vdev stack, - * just execute the interlock stages to clean up. - */ - if (zio->io_error && - ((1U << zio->io_stage) & ZIO_VDEV_IO_STAGES) == 0) - pipeline &= ZIO_ERROR_PIPELINE_MASK; - - while (((1U << ++zio->io_stage) & pipeline) == 0) - continue; - - ASSERT(zio->io_stage <= ZIO_STAGE_DONE); - ASSERT(zio->io_stalled == 0); - - rv = zio_pipeline[zio->io_stage](zio); - - if (rv == ZIO_PIPELINE_STOP) - return; - - ASSERT(rv == ZIO_PIPELINE_CONTINUE); - } -} - -static boolean_t -zio_io_should_fail(uint16_t range) -{ - static uint16_t allocs = 0; - - return (P2PHASE(allocs++, 1U<blk_dva[0]. - * We use that as a hint for which vdev to allocate from next. - */ - error = metaslab_alloc(spa, spa->spa_log_class, size, - new_bp, 1, txg, old_bp, B_TRUE); - - if (error) - error = metaslab_alloc(spa, spa->spa_normal_class, size, - new_bp, 1, txg, old_bp, B_TRUE); - - if (error == 0) { - BP_SET_LSIZE(new_bp, size); - BP_SET_PSIZE(new_bp, size); - BP_SET_COMPRESS(new_bp, ZIO_COMPRESS_OFF); - BP_SET_CHECKSUM(new_bp, ZIO_CHECKSUM_ZILOG); - BP_SET_TYPE(new_bp, DMU_OT_INTENT_LOG); - BP_SET_LEVEL(new_bp, 0); - BP_SET_BYTEORDER(new_bp, ZFS_HOST_BYTEORDER); - new_bp->blk_birth = txg; - } - - spa_config_exit(spa, FTAG); - - return (error); -} - -/* - * Free an intent log block. We know it can't be a gang block, so there's - * nothing to do except metaslab_free() it. - */ -void -zio_free_blk(spa_t *spa, blkptr_t *bp, uint64_t txg) -{ - ASSERT(!BP_IS_GANG(bp)); - - spa_config_enter(spa, RW_READER, FTAG); - - metaslab_free(spa, bp, txg, B_FALSE); - - spa_config_exit(spa, FTAG); -} - -/* - * start an async flush of the write cache for this vdev - */ -void -zio_flush(zio_t *zio, vdev_t *vd) -{ - zio_nowait(zio_ioctl(zio, zio->io_spa, vd, DKIOCFLUSHWRITECACHE, - NULL, NULL, ZIO_PRIORITY_NOW, - ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_RETRY)); -} diff --git a/zfs/lib/libzpool/zio_checksum.c b/zfs/lib/libzpool/zio_checksum.c index f79254ef6..bf7fe733f 100644 --- a/zfs/lib/libzpool/zio_checksum.c +++ b/zfs/lib/libzpool/zio_checksum.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zio_checksum.c 1.6 06/11/10 SMI" - #include #include #include @@ -95,26 +93,60 @@ zio_checksum_select(uint8_t child, uint8_t parent) return (child); } +/* + * Set the external verifier for a gang block based on , + * a tuple which is guaranteed to be unique for the life of the pool. + */ +static void +zio_checksum_gang_verifier(zio_cksum_t *zcp, blkptr_t *bp) +{ + dva_t *dva = BP_IDENTITY(bp); + uint64_t txg = bp->blk_birth; + + ASSERT(BP_IS_GANG(bp)); + + ZIO_SET_CHECKSUM(zcp, DVA_GET_VDEV(dva), DVA_GET_OFFSET(dva), txg, 0); +} + +/* + * Set the external verifier for a label block based on its offset. + * The vdev is implicit, and the txg is unknowable at pool open time -- + * hence the logic in vdev_uberblock_load() to find the most recent copy. + */ +static void +zio_checksum_label_verifier(zio_cksum_t *zcp, uint64_t offset) +{ + ZIO_SET_CHECKSUM(zcp, offset, 0, 0, 0); +} + /* * Generate the checksum. */ void -zio_checksum(uint_t checksum, zio_cksum_t *zcp, void *data, uint64_t size) +zio_checksum_compute(zio_t *zio, enum zio_checksum checksum, + void *data, uint64_t size) { + blkptr_t *bp = zio->io_bp; + uint64_t offset = zio->io_offset; zio_block_tail_t *zbt = (zio_block_tail_t *)((char *)data + size) - 1; zio_checksum_info_t *ci = &zio_checksum_table[checksum]; zio_cksum_t zbt_cksum; - ASSERT(checksum < ZIO_CHECKSUM_FUNCTIONS); + ASSERT((uint_t)checksum < ZIO_CHECKSUM_FUNCTIONS); ASSERT(ci->ci_func[0] != NULL); if (ci->ci_zbt) { - *zcp = zbt->zbt_cksum; + if (checksum == ZIO_CHECKSUM_GANG_HEADER) + zio_checksum_gang_verifier(&zbt->zbt_cksum, bp); + else if (checksum == ZIO_CHECKSUM_LABEL) + zio_checksum_label_verifier(&zbt->zbt_cksum, offset); + else + bp->blk_cksum = zbt->zbt_cksum; zbt->zbt_magic = ZBT_MAGIC; ci->ci_func[0](data, size, &zbt_cksum); zbt->zbt_cksum = zbt_cksum; } else { - ci->ci_func[0](data, size, zcp); + ci->ci_func[0](data, size, &bp->blk_cksum); } } @@ -122,47 +154,49 @@ int zio_checksum_error(zio_t *zio) { blkptr_t *bp = zio->io_bp; - zio_cksum_t zc = bp->blk_cksum; - uint_t checksum = BP_IS_GANG(bp) ? ZIO_CHECKSUM_GANG_HEADER : - BP_GET_CHECKSUM(bp); - int byteswap = BP_SHOULD_BYTESWAP(bp); + uint_t checksum = (bp == NULL ? zio->io_prop.zp_checksum : + (BP_IS_GANG(bp) ? ZIO_CHECKSUM_GANG_HEADER : BP_GET_CHECKSUM(bp))); + int byteswap; void *data = zio->io_data; - uint64_t size = ZIO_GET_IOSIZE(zio); + uint64_t size = (bp == NULL ? zio->io_size : + (BP_IS_GANG(bp) ? SPA_GANGBLOCKSIZE : BP_GET_PSIZE(bp))); + uint64_t offset = zio->io_offset; zio_block_tail_t *zbt = (zio_block_tail_t *)((char *)data + size) - 1; zio_checksum_info_t *ci = &zio_checksum_table[checksum]; - zio_cksum_t actual_cksum, expected_cksum; + zio_cksum_t actual_cksum, expected_cksum, verifier; if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL) return (EINVAL); if (ci->ci_zbt) { if (checksum == ZIO_CHECKSUM_GANG_HEADER) - zio_set_gang_verifier(zio, &zc); + zio_checksum_gang_verifier(&verifier, bp); + else if (checksum == ZIO_CHECKSUM_LABEL) + zio_checksum_label_verifier(&verifier, offset); + else + verifier = bp->blk_cksum; - if (zbt->zbt_magic == BSWAP_64(ZBT_MAGIC)) { - expected_cksum = zbt->zbt_cksum; + byteswap = (zbt->zbt_magic == BSWAP_64(ZBT_MAGIC)); + + if (byteswap) + byteswap_uint64_array(&verifier, sizeof (zio_cksum_t)); + + expected_cksum = zbt->zbt_cksum; + zbt->zbt_cksum = verifier; + ci->ci_func[byteswap](data, size, &actual_cksum); + zbt->zbt_cksum = expected_cksum; + + if (byteswap) byteswap_uint64_array(&expected_cksum, sizeof (zio_cksum_t)); - zbt->zbt_cksum = zc; - byteswap_uint64_array(&zbt->zbt_cksum, - sizeof (zio_cksum_t)); - ci->ci_func[1](data, size, &actual_cksum); - zbt->zbt_cksum = expected_cksum; - byteswap_uint64_array(&zbt->zbt_cksum, - sizeof (zio_cksum_t)); - } else { - expected_cksum = zbt->zbt_cksum; - zbt->zbt_cksum = zc; - ci->ci_func[0](data, size, &actual_cksum); - zbt->zbt_cksum = expected_cksum; - } - zc = expected_cksum; } else { ASSERT(!BP_IS_GANG(bp)); + byteswap = BP_SHOULD_BYTESWAP(bp); + expected_cksum = bp->blk_cksum; ci->ci_func[byteswap](data, size, &actual_cksum); } - if (!ZIO_CHECKSUM_EQUAL(actual_cksum, zc)) + if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum)) return (ECKSUM); if (zio_injection_enabled && !zio->io_error) diff --git a/zfs/lib/libzpool/zio_compress.c b/zfs/lib/libzpool/zio_compress.c index 190c4ead8..c563be4eb 100644 --- a/zfs/lib/libzpool/zio_compress.c +++ b/zfs/lib/libzpool/zio_compress.c @@ -24,7 +24,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zio_compress.c 1.4 07/03/22 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/lib/libzpool/zio_inject.c b/zfs/lib/libzpool/zio_inject.c index 30a938816..b3469fdd5 100644 --- a/zfs/lib/libzpool/zio_inject.c +++ b/zfs/lib/libzpool/zio_inject.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zio_inject.c 1.2 07/12/07 SMI" - /* * ZFS fault injection * @@ -47,6 +45,7 @@ #include #include #include +#include uint32_t zio_injection_enabled; @@ -145,6 +144,56 @@ zio_handle_fault_injection(zio_t *zio, int error) return (ret); } +/* + * Determine if the zio is part of a label update and has an injection + * handler associated with that portion of the label. Currently, we + * allow error injection in either the nvlist or the uberblock region of + * of the vdev label. + */ +int +zio_handle_label_injection(zio_t *zio, int error) +{ + inject_handler_t *handler; + vdev_t *vd = zio->io_vd; + uint64_t offset = zio->io_offset; + int label; + int ret = 0; + + if (offset + zio->io_size > VDEV_LABEL_START_SIZE && + offset < vd->vdev_psize - VDEV_LABEL_END_SIZE) + return (0); + + rw_enter(&inject_lock, RW_READER); + + for (handler = list_head(&inject_handlers); handler != NULL; + handler = list_next(&inject_handlers, handler)) { + uint64_t start = handler->zi_record.zi_start; + uint64_t end = handler->zi_record.zi_end; + + /* Ignore device only faults */ + if (handler->zi_record.zi_start == 0) + continue; + + /* + * The injection region is the relative offsets within a + * vdev label. We must determine the label which is being + * updated and adjust our region accordingly. + */ + label = vdev_label_number(vd->vdev_psize, offset); + start = vdev_label_offset(vd->vdev_psize, label, start); + end = vdev_label_offset(vd->vdev_psize, label, end); + + if (zio->io_vd->vdev_guid == handler->zi_record.zi_guid && + (offset >= start && offset <= end)) { + ret = error; + break; + } + } + rw_exit(&inject_lock); + return (ret); +} + + int zio_handle_device_injection(vdev_t *vd, int error) { @@ -156,6 +205,10 @@ zio_handle_device_injection(vdev_t *vd, int error) for (handler = list_head(&inject_handlers); handler != NULL; handler = list_next(&inject_handlers, handler)) { + /* Ignore label specific faults */ + if (handler->zi_record.zi_start != 0) + continue; + if (vd->vdev_guid == handler->zi_record.zi_guid) { if (handler->zi_record.zi_error == error) { /* @@ -304,6 +357,7 @@ zio_clear_fault(int id) void zio_inject_init(void) { + rw_init(&inject_lock, NULL, RW_DEFAULT, NULL); list_create(&inject_handlers, sizeof (inject_handler_t), offsetof(inject_handler_t, zi_link)); } @@ -312,4 +366,5 @@ void zio_inject_fini(void) { list_destroy(&inject_handlers); + rw_destroy(&inject_lock); } diff --git a/zfs/lib/libdmu-ctl/zvol.c b/zfs/lib/libzpool/zvol.c similarity index 76% rename from zfs/lib/libdmu-ctl/zvol.c rename to zfs/lib/libzpool/zvol.c index 5d16a4d1f..4e993060c 100644 --- a/zfs/lib/libdmu-ctl/zvol.c +++ b/zfs/lib/libzpool/zvol.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zvol.c 1.31 08/04/09 SMI" - /* * ZFS volume emulation driver. * @@ -93,22 +91,12 @@ static void *zvol_state; static kmutex_t zvol_state_lock; static uint32_t zvol_minors; -#define NUM_EXTENTS ((SPA_MAXBLOCKSIZE) / sizeof (zvol_extent_t)) - typedef struct zvol_extent { + list_node_t ze_node; dva_t ze_dva; /* dva associated with this extent */ - uint64_t ze_stride; /* extent stride */ - uint64_t ze_size; /* number of blocks in extent */ + uint64_t ze_nblks; /* number of blocks in extent */ } zvol_extent_t; -/* - * The list of extents associated with the dump device - */ -typedef struct zvol_ext_list { - zvol_extent_t zl_extents[NUM_EXTENTS]; - struct zvol_ext_list *zl_next; -} zvol_ext_list_t; - /* * The in-core state of each volume. */ @@ -124,7 +112,7 @@ typedef struct zvol_state { uint32_t zv_open_count[OTYPCNT]; /* open counts */ uint32_t zv_total_opens; /* total open count */ zilog_t *zv_zilog; /* ZIL handle */ - zvol_ext_list_t *zv_list; /* List of extents for dump */ + list_t zv_extents; /* List of extents for dump */ uint64_t zv_txg_assign; /* txg to assign during ZIL replay */ znode_t zv_znode; /* for range locking */ } zvol_state_t; @@ -134,6 +122,7 @@ typedef struct zvol_state { */ #define ZVOL_RDONLY 0x1 #define ZVOL_DUMPIFIED 0x2 +#define ZVOL_EXCL 0x4 /* * zvol maximum transfer in one DMU tx. @@ -259,128 +248,81 @@ zvol_minor_lookup(const char *name) return (zv); } -void -zvol_init_extent(zvol_extent_t *ze, blkptr_t *bp) -{ - ze->ze_dva = bp->blk_dva[0]; /* structure assignment */ - ze->ze_stride = 0; - ze->ze_size = 1; -} - /* extent mapping arg */ struct maparg { - zvol_ext_list_t *ma_list; - zvol_extent_t *ma_extent; - int ma_gang; + zvol_state_t *ma_zv; + uint64_t ma_blks; }; /*ARGSUSED*/ static int -zvol_map_block(traverse_blk_cache_t *bc, spa_t *spa, void *arg) +zvol_map_block(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb, + const dnode_phys_t *dnp, void *arg) { - zbookmark_t *zb = &bc->bc_bookmark; - blkptr_t *bp = &bc->bc_blkptr; - void *data = bc->bc_data; - dnode_phys_t *dnp = bc->bc_dnode; - struct maparg *ma = (struct maparg *)arg; - uint64_t stride; + struct maparg *ma = arg; + zvol_extent_t *ze; + int bs = ma->ma_zv->zv_volblocksize; - /* If there is an error, then keep trying to make progress */ - if (bc->bc_errno) - return (ERESTART); - -#ifdef ZFS_DEBUG - if (zb->zb_level == -1) { - ASSERT3U(BP_GET_TYPE(bp), ==, DMU_OT_OBJSET); - ASSERT3U(BP_GET_LEVEL(bp), ==, 0); - } else { - ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type); - ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level); - } - - if (zb->zb_level > 0) { - uint64_t fill = 0; - blkptr_t *bpx, *bpend; - - for (bpx = data, bpend = bpx + BP_GET_LSIZE(bp) / sizeof (*bpx); - bpx < bpend; bpx++) { - if (bpx->blk_birth != 0) { - fill += bpx->blk_fill; - } else { - ASSERT(bpx->blk_fill == 0); - } - } - ASSERT3U(fill, ==, bp->blk_fill); - } - - if (zb->zb_level == 0 && dnp->dn_type == DMU_OT_DNODE) { - uint64_t fill = 0; - dnode_phys_t *dnx, *dnend; - - for (dnx = data, dnend = dnx + (BP_GET_LSIZE(bp)>>DNODE_SHIFT); - dnx < dnend; dnx++) { - if (dnx->dn_type != DMU_OT_NONE) - fill++; - } - ASSERT3U(fill, ==, bp->blk_fill); - } -#endif - - if (zb->zb_level || dnp->dn_type == DMU_OT_DNODE) + if (bp == NULL || zb->zb_object != ZVOL_OBJ || zb->zb_level != 0) return (0); + VERIFY3U(ma->ma_blks, ==, zb->zb_blkid); + ma->ma_blks++; + /* Abort immediately if we have encountered gang blocks */ - if (BP_IS_GANG(bp)) { - ma->ma_gang++; - return (EINTR); - } + if (BP_IS_GANG(bp)) + return (EFRAGS); - /* first time? */ - if (ma->ma_extent->ze_size == 0) { - zvol_init_extent(ma->ma_extent, bp); + /* + * See if the block is at the end of the previous extent. + */ + ze = list_tail(&ma->ma_zv->zv_extents); + if (ze && + DVA_GET_VDEV(BP_IDENTITY(bp)) == DVA_GET_VDEV(&ze->ze_dva) && + DVA_GET_OFFSET(BP_IDENTITY(bp)) == + DVA_GET_OFFSET(&ze->ze_dva) + ze->ze_nblks * bs) { + ze->ze_nblks++; return (0); } - stride = (DVA_GET_OFFSET(&bp->blk_dva[0])) - - ((DVA_GET_OFFSET(&ma->ma_extent->ze_dva)) + - (ma->ma_extent->ze_size - 1) * (ma->ma_extent->ze_stride)); - if (DVA_GET_VDEV(BP_IDENTITY(bp)) == - DVA_GET_VDEV(&ma->ma_extent->ze_dva)) { - if (ma->ma_extent->ze_stride == 0) { - /* second block in this extent */ - ma->ma_extent->ze_stride = stride; - ma->ma_extent->ze_size++; - return (0); - } else if (ma->ma_extent->ze_stride == stride) { - /* - * the block we allocated has the same - * stride - */ - ma->ma_extent->ze_size++; - return (0); - } + dprintf_bp(bp, "%s", "next blkptr:"); + + /* start a new extent */ + ze = kmem_zalloc(sizeof (zvol_extent_t), KM_SLEEP); + ze->ze_dva = bp->blk_dva[0]; /* structure assignment */ + ze->ze_nblks = 1; + list_insert_tail(&ma->ma_zv->zv_extents, ze); + return (0); +} + +static void +zvol_free_extents(zvol_state_t *zv) +{ + zvol_extent_t *ze; + + while (ze = list_head(&zv->zv_extents)) { + list_remove(&zv->zv_extents, ze); + kmem_free(ze, sizeof (zvol_extent_t)); + } +} + +static int +zvol_get_lbas(zvol_state_t *zv) +{ + struct maparg ma; + int err; + + ma.ma_zv = zv; + ma.ma_blks = 0; + zvol_free_extents(zv); + + err = traverse_dataset(dmu_objset_ds(zv->zv_objset), 0, + TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA, zvol_map_block, &ma); + if (err || ma.ma_blks != (zv->zv_volsize / zv->zv_volblocksize)) { + zvol_free_extents(zv); + return (err ? err : EIO); } - /* - * dtrace -n 'zfs-dprintf - * /stringof(arg0) == "zvol.c"/ - * { - * printf("%s: %s", stringof(arg1), stringof(arg3)) - * } ' - */ - dprintf("ma_extent 0x%lx mrstride 0x%lx stride %lx\n", - ma->ma_extent->ze_size, ma->ma_extent->ze_stride, stride); - dprintf_bp(bp, "%s", "next blkptr:"); - /* start a new extent */ - if (ma->ma_extent == &ma->ma_list->zl_extents[NUM_EXTENTS - 1]) { - ma->ma_list->zl_next = kmem_zalloc(sizeof (zvol_ext_list_t), - KM_SLEEP); - ma->ma_list = ma->ma_list->zl_next; - ma->ma_extent = &ma->ma_list->zl_extents[0]; - } else { - ma->ma_extent++; - } - zvol_init_extent(ma->ma_extent, bp); return (0); } @@ -477,106 +419,6 @@ zil_replay_func_t *zvol_replay_vector[TX_MAX_TYPE] = { zvol_replay_err, /* TX_ACL */ }; -/* - * reconstruct dva that gets us to the desired offset (offset - * is in bytes) - */ -int -zvol_get_dva(zvol_state_t *zv, uint64_t offset, dva_t *dva) -{ - zvol_ext_list_t *zl; - zvol_extent_t *ze; - int idx; - uint64_t tmp; - - if ((zl = zv->zv_list) == NULL) - return (EIO); - idx = 0; - ze = &zl->zl_extents[0]; - while (offset >= ze->ze_size * zv->zv_volblocksize) { - offset -= ze->ze_size * zv->zv_volblocksize; - - if (idx == NUM_EXTENTS - 1) { - /* we've reached the end of this array */ - ASSERT(zl->zl_next != NULL); - if (zl->zl_next == NULL) - return (-1); - zl = zl->zl_next; - ze = &zl->zl_extents[0]; - idx = 0; - } else { - ze++; - idx++; - } - } - DVA_SET_VDEV(dva, DVA_GET_VDEV(&ze->ze_dva)); - tmp = DVA_GET_OFFSET((&ze->ze_dva)); - tmp += (ze->ze_stride * (offset / zv->zv_volblocksize)); - DVA_SET_OFFSET(dva, tmp); - return (0); -} - -static void -zvol_free_extents(zvol_state_t *zv) -{ - zvol_ext_list_t *zl; - zvol_ext_list_t *tmp; - - if (zv->zv_list != NULL) { - zl = zv->zv_list; - while (zl != NULL) { - tmp = zl->zl_next; - kmem_free(zl, sizeof (zvol_ext_list_t)); - zl = tmp; - } - zv->zv_list = NULL; - } -} - -int -zvol_get_lbas(zvol_state_t *zv) -{ - struct maparg ma; - zvol_ext_list_t *zl; - zvol_extent_t *ze; - uint64_t blocks = 0; - int err; - - ma.ma_list = zl = kmem_zalloc(sizeof (zvol_ext_list_t), KM_SLEEP); - ma.ma_extent = &ma.ma_list->zl_extents[0]; - ma.ma_gang = 0; - zv->zv_list = ma.ma_list; - - err = traverse_zvol(zv->zv_objset, ADVANCE_PRE, zvol_map_block, &ma); - if (err == EINTR && ma.ma_gang) { - /* - * We currently don't support dump devices when the pool - * is so fragmented that our allocation has resulted in - * gang blocks. - */ - zvol_free_extents(zv); - return (EFRAGS); - } - ASSERT3U(err, ==, 0); - - ze = &zl->zl_extents[0]; - while (ze) { - blocks += ze->ze_size; - if (ze == &zl->zl_extents[NUM_EXTENTS - 1]) { - zl = zl->zl_next; - ze = &zl->zl_extents[0]; - } else { - ze++; - } - } - if (blocks != (zv->zv_volsize / zv->zv_volblocksize)) { - zvol_free_extents(zv); - return (EIO); - } - - return (0); -} - /* * Create a minor node (plus a whole lot more) for the specified volume. */ @@ -589,7 +431,7 @@ zvol_create_minor(const char *name, major_t maj) uint64_t volsize; minor_t minor = 0; struct pathname linkpath; - int ds_mode = DS_MODE_PRIMARY; + int ds_mode = DS_MODE_OWNER; vnode_t *vp = NULL; char *devpath; size_t devpathlen = strlen(ZVOL_FULL_DEV_DIR) + strlen(name) + 1; @@ -709,12 +551,14 @@ zvol_create_minor(const char *name, major_t maj) mutex_init(&zv->zv_znode.z_range_lock, NULL, MUTEX_DEFAULT, NULL); avl_create(&zv->zv_znode.z_range_avl, zfs_range_compare, sizeof (rl_t), offsetof(rl_t, r_node)); + list_create(&zv->zv_extents, sizeof (zvol_extent_t), + offsetof(zvol_extent_t, ze_node)); /* get and cache the blocksize */ error = dmu_object_info(os, ZVOL_OBJ, &doi); ASSERT(error == 0); zv->zv_volblocksize = doi.doi_data_block_size; - zil_replay(os, zv, &zv->zv_txg_assign, zvol_replay_vector); + zil_replay(os, zv, &zv->zv_txg_assign, zvol_replay_vector, NULL); zvol_size_changed(zv, maj); /* XXX this should handle the possible i/o error */ @@ -774,30 +618,11 @@ zvol_remove_minor(const char *name) return (0); } -static int -zvol_truncate(zvol_state_t *zv, uint64_t offset, uint64_t size) -{ - dmu_tx_t *tx; - int error; - - tx = dmu_tx_create(zv->zv_objset); - dmu_tx_hold_free(tx, ZVOL_OBJ, offset, size); - error = dmu_tx_assign(tx, TXG_WAIT); - if (error) { - dmu_tx_abort(tx); - return (error); - } - error = dmu_free_range(zv->zv_objset, ZVOL_OBJ, offset, size, tx); - dmu_tx_commit(tx); - return (0); -} - int zvol_prealloc(zvol_state_t *zv) { objset_t *os = zv->zv_objset; dmu_tx_t *tx; - void *data; uint64_t refd, avail, usedobjs, availobjs; uint64_t resid = zv->zv_volsize; uint64_t off = 0; @@ -810,9 +635,6 @@ zvol_prealloc(zvol_state_t *zv) /* Free old extents if they exist */ zvol_free_extents(zv); - /* allocate the blocks by writing each one */ - data = kmem_zalloc(SPA_MAXBLOCKSIZE, KM_SLEEP); - while (resid != 0) { int error; uint64_t bytes = MIN(resid, SPA_MAXBLOCKSIZE); @@ -822,16 +644,14 @@ zvol_prealloc(zvol_state_t *zv) error = dmu_tx_assign(tx, TXG_WAIT); if (error) { dmu_tx_abort(tx); - kmem_free(data, SPA_MAXBLOCKSIZE); - (void) zvol_truncate(zv, 0, off); + (void) dmu_free_long_range(os, ZVOL_OBJ, 0, off); return (error); } - dmu_write(os, ZVOL_OBJ, off, bytes, data, tx); + dmu_prealloc(os, ZVOL_OBJ, off, bytes, tx); dmu_tx_commit(tx); off += bytes; resid -= bytes; } - kmem_free(data, SPA_MAXBLOCKSIZE); txg_wait_synced(dmu_objset_pool(os), 0); return (0); @@ -847,7 +667,6 @@ zvol_update_volsize(zvol_state_t *zv, major_t maj, uint64_t volsize) tx = dmu_tx_create(zv->zv_objset); dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL); - dmu_tx_hold_free(tx, ZVOL_OBJ, volsize, DMU_OBJECT_END); error = dmu_tx_assign(tx, TXG_WAIT); if (error) { dmu_tx_abort(tx); @@ -859,9 +678,14 @@ zvol_update_volsize(zvol_state_t *zv, major_t maj, uint64_t volsize) dmu_tx_commit(tx); if (error == 0) - error = zvol_truncate(zv, volsize, DMU_OBJECT_END); + error = dmu_free_long_range(zv->zv_objset, + ZVOL_OBJ, volsize, DMU_OBJECT_END); - if (error == 0) { + /* + * If we are using a faked-up state (zv_minor == 0) then don't + * try to update the in-core zvol state. + */ + if (error == 0 && zv->zv_minor) { zv->zv_volsize = volsize; zvol_size_changed(zv, maj); } @@ -875,25 +699,31 @@ zvol_set_volsize(const char *name, major_t maj, uint64_t volsize) int error; dmu_object_info_t doi; uint64_t old_volsize = 0ULL; + zvol_state_t state = { 0 }; mutex_enter(&zvol_state_lock); if ((zv = zvol_minor_lookup(name)) == NULL) { - mutex_exit(&zvol_state_lock); - return (ENXIO); + /* + * If we are doing a "zfs clone -o volsize=", then the + * minor node won't exist yet. + */ + error = dmu_objset_open(name, DMU_OST_ZVOL, DS_MODE_OWNER, + &state.zv_objset); + if (error != 0) + goto out; + zv = &state; } old_volsize = zv->zv_volsize; if ((error = dmu_object_info(zv->zv_objset, ZVOL_OBJ, &doi)) != 0 || (error = zvol_check_volsize(volsize, - doi.doi_data_block_size)) != 0) { - mutex_exit(&zvol_state_lock); - return (error); - } + doi.doi_data_block_size)) != 0) + goto out; if (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY)) { - mutex_exit(&zvol_state_lock); - return (EROFS); + error = EROFS; + goto out; } error = zvol_update_volsize(zv, maj, volsize); @@ -911,6 +741,10 @@ zvol_set_volsize(const char *name, major_t maj, uint64_t volsize) } } +out: + if (state.zv_objset) + dmu_objset_close(state.zv_objset); + mutex_exit(&zvol_state_lock); return (error); @@ -922,15 +756,24 @@ zvol_set_volblocksize(const char *name, uint64_t volblocksize) zvol_state_t *zv; dmu_tx_t *tx; int error; + boolean_t needlock; - mutex_enter(&zvol_state_lock); + /* + * The lock may already be held if we are being called from + * zvol_dump_init(). + */ + needlock = !MUTEX_HELD(&zvol_state_lock); + if (needlock) + mutex_enter(&zvol_state_lock); if ((zv = zvol_minor_lookup(name)) == NULL) { - mutex_exit(&zvol_state_lock); + if (needlock) + mutex_exit(&zvol_state_lock); return (ENXIO); } if (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY)) { - mutex_exit(&zvol_state_lock); + if (needlock) + mutex_exit(&zvol_state_lock); return (EROFS); } @@ -945,9 +788,12 @@ zvol_set_volblocksize(const char *name, uint64_t volblocksize) if (error == ENOTSUP) error = EBUSY; dmu_tx_commit(tx); + if (error == 0) + zv->zv_volblocksize = volblocksize; } - mutex_exit(&zvol_state_lock); + if (needlock) + mutex_exit(&zvol_state_lock); return (error); } @@ -977,6 +823,17 @@ zvol_open(dev_t *devp, int flag, int otyp, cred_t *cr) mutex_exit(&zvol_state_lock); return (EROFS); } + if (zv->zv_flags & ZVOL_EXCL) { + mutex_exit(&zvol_state_lock); + return (EBUSY); + } + if (flag & FEXCL) { + if (zv->zv_total_opens != 0) { + mutex_exit(&zvol_state_lock); + return (EBUSY); + } + zv->zv_flags |= ZVOL_EXCL; + } if (zv->zv_open_count[otyp] == 0 || otyp == OTYP_LYR) { zv->zv_open_count[otyp]++; @@ -1006,13 +863,9 @@ zvol_close(dev_t dev, int flag, int otyp, cred_t *cr) return (ENXIO); } - /* - * The next statement is a workaround for the following DDI bug: - * 6343604 specfs race: multiple "last-close" of the same device - */ - if (zv->zv_total_opens == 0) { - mutex_exit(&zvol_state_lock); - return (0); + if (zv->zv_flags & ZVOL_EXCL) { + ASSERT(zv->zv_total_opens == 1); + zv->zv_flags &= ~ZVOL_EXCL; } /* @@ -1140,20 +993,21 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t len) } } -int -zvol_dumpio(vdev_t *vd, uint64_t size, uint64_t offset, void *addr, - int bflags, int isdump) +static int +zvol_dumpio_vdev(vdev_t *vd, void *addr, uint64_t offset, uint64_t size, + boolean_t doread, boolean_t isdump) { vdev_disk_t *dvd; - int direction; int c; int numerrors = 0; for (c = 0; c < vd->vdev_children; c++) { - if (zvol_dumpio(vd->vdev_child[c], size, offset, - addr, bflags, isdump) != 0) { + ASSERT(vd->vdev_ops == &vdev_mirror_ops); + int err = zvol_dumpio_vdev(vd->vdev_child[c], + addr, offset, size, doread, isdump); + if (err != 0) { numerrors++; - } else if (bflags & B_READ) { + } else if (doread) { break; } } @@ -1161,52 +1015,54 @@ zvol_dumpio(vdev_t *vd, uint64_t size, uint64_t offset, void *addr, if (!vd->vdev_ops->vdev_op_leaf) return (numerrors < vd->vdev_children ? 0 : EIO); - if (!vdev_writeable(vd)) + if (doread && !vdev_readable(vd)) + return (EIO); + else if (!doread && !vdev_writeable(vd)) return (EIO); dvd = vd->vdev_tsd; ASSERT3P(dvd, !=, NULL); - direction = bflags & (B_WRITE | B_READ); - ASSERT(ISP2(direction)); offset += VDEV_LABEL_START_SIZE; if (ddi_in_panic() || isdump) { - if (direction & B_READ) + ASSERT(!doread); + if (doread) return (EIO); return (ldi_dump(dvd->vd_lh, addr, lbtodb(offset), lbtodb(size))); } else { return (vdev_disk_physio(dvd->vd_lh, addr, size, offset, - direction)); + doread ? B_READ : B_WRITE)); } } -int -zvol_physio(zvol_state_t *zv, int bflags, uint64_t off, - uint64_t size, void *addr, int isdump) +static int +zvol_dumpio(zvol_state_t *zv, void *addr, uint64_t offset, uint64_t size, + boolean_t doread, boolean_t isdump) { - dva_t dva; vdev_t *vd; int error; + zvol_extent_t *ze; spa_t *spa = dmu_objset_spa(zv->zv_objset); + /* Must be sector aligned, and not stradle a block boundary. */ + if (P2PHASE(offset, DEV_BSIZE) || P2PHASE(size, DEV_BSIZE) || + P2BOUNDARY(offset, size, zv->zv_volblocksize)) { + return (EINVAL); + } ASSERT(size <= zv->zv_volblocksize); - /* restrict requests to multiples of the system block size */ - if (P2PHASE(off, DEV_BSIZE) || P2PHASE(size, DEV_BSIZE)) - return (EINVAL); - - if (zvol_get_dva(zv, off, &dva) != 0) - return (EIO); - - spa_config_enter(spa, RW_READER, FTAG); - vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva)); - - error = zvol_dumpio(vd, size, - DVA_GET_OFFSET(&dva) + (off % zv->zv_volblocksize), - addr, bflags & (B_READ | B_WRITE | B_PHYS), isdump); - - spa_config_exit(spa, FTAG); + /* Locate the extent this belongs to */ + ze = list_head(&zv->zv_extents); + while (offset >= ze->ze_nblks * zv->zv_volblocksize) { + offset -= ze->ze_nblks * zv->zv_volblocksize; + ze = list_next(&zv->zv_extents, ze); + } + spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); + vd = vdev_lookup_top(spa, DVA_GET_VDEV(&ze->ze_dva)); + offset += DVA_GET_OFFSET(&ze->ze_dva); + error = zvol_dumpio_vdev(vd, addr, offset, size, doread, isdump); + spa_config_exit(spa, SCL_STATE, FTAG); return (error); } @@ -1215,12 +1071,13 @@ zvol_strategy(buf_t *bp) { zvol_state_t *zv = ddi_get_soft_state(zvol_state, getminor(bp->b_edev)); uint64_t off, volsize; - size_t size, resid; + size_t resid; char *addr; objset_t *os; rl_t *rl; int error = 0; - boolean_t reading, is_dump = zv->zv_flags & ZVOL_DUMPIFIED; + boolean_t doread = bp->b_flags & B_READ; + boolean_t is_dump = zv->zv_flags & ZVOL_DUMPIFIED; if (zv == NULL) { bioerror(bp, ENXIO); @@ -1252,26 +1109,26 @@ zvol_strategy(buf_t *bp) addr = bp->b_un.b_addr; resid = bp->b_bcount; + if (resid > 0 && (off < 0 || off >= volsize)) { + bioerror(bp, EIO); + biodone(bp); + return (0); + } + /* * There must be no buffer changes when doing a dmu_sync() because * we can't change the data whilst calculating the checksum. */ - reading = bp->b_flags & B_READ; rl = zfs_range_lock(&zv->zv_znode, off, resid, - reading ? RL_READER : RL_WRITER); - - if (resid > volsize - off) /* don't write past the end */ - resid = volsize - off; + doread ? RL_READER : RL_WRITER); while (resid != 0 && off < volsize) { - - size = MIN(resid, zvol_maxphys); + size_t size = MIN(resid, zvol_maxphys); if (is_dump) { - /* can't straddle a block boundary */ size = MIN(size, P2END(off, zv->zv_volblocksize) - off); - error = zvol_physio(zv, bp->b_flags, off, size, - addr, 0); - } else if (reading) { + error = zvol_dumpio(zv, addr, off, size, + doread, B_FALSE); + } else if (doread) { error = dmu_read(os, ZVOL_OBJ, off, size, addr); } else { dmu_tx_t *tx = dmu_tx_create(os); @@ -1285,8 +1142,12 @@ zvol_strategy(buf_t *bp) dmu_tx_commit(tx); } } - if (error) + if (error) { + /* convert checksum errors into IO errors */ + if (error == ECKSUM) + error = EIO; break; + } off += size; addr += size; resid -= size; @@ -1296,7 +1157,7 @@ zvol_strategy(buf_t *bp) if ((bp->b_resid = resid) == bp->b_bcount) bioerror(bp, off > volsize ? EINVAL : error); - if (!(bp->b_flags & B_ASYNC) && !reading && !zil_disable && !is_dump) + if (!(bp->b_flags & B_ASYNC) && !doread && !zil_disable && !is_dump) zil_commit(zv->zv_zilog, UINT64_MAX, ZVOL_OBJ); biodone(bp); @@ -1337,16 +1198,12 @@ zvol_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblocks) boff = ldbtob(blkno); resid = ldbtob(nblocks); - if (boff + resid > zv->zv_volsize) { - /* dump should know better than to write here */ - ASSERT(blkno + resid <= zv->zv_volsize); - return (EIO); - } - while (resid) { - /* can't straddle a block boundary */ - size = MIN(resid, P2END(boff, zv->zv_volblocksize) - boff); - error = zvol_physio(zv, B_WRITE, boff, size, addr, 1); + VERIFY3U(boff + resid, <=, zv->zv_volsize); + + while (resid) { + size = MIN(resid, P2END(boff, zv->zv_volblocksize) - boff); + error = zvol_dumpio(zv, addr, boff, size, B_FALSE, B_TRUE); if (error) break; boff += size; @@ -1363,6 +1220,7 @@ zvol_read(dev_t dev, uio_t *uio, cred_t *cr) { minor_t minor = getminor(dev); zvol_state_t *zv; + uint64_t volsize; rl_t *rl; int error = 0; @@ -1373,14 +1231,33 @@ zvol_read(dev_t dev, uio_t *uio, cred_t *cr) if (zv == NULL) return (ENXIO); + volsize = zv->zv_volsize; + if (uio->uio_resid > 0 && + (uio->uio_loffset < 0 || uio->uio_loffset >= volsize)) + return (EIO); + + if (zv->zv_flags & ZVOL_DUMPIFIED) { + error = physio(zvol_strategy, NULL, dev, B_READ, + zvol_minphys, uio); + return (error); + } + rl = zfs_range_lock(&zv->zv_znode, uio->uio_loffset, uio->uio_resid, RL_READER); - while (uio->uio_resid > 0) { + while (uio->uio_resid > 0 && uio->uio_loffset < volsize) { uint64_t bytes = MIN(uio->uio_resid, DMU_MAX_ACCESS >> 1); + /* don't read past the end */ + if (bytes > volsize - uio->uio_loffset) + bytes = volsize - uio->uio_loffset; + error = dmu_read_uio(zv->zv_objset, ZVOL_OBJ, uio, bytes); - if (error) + if (error) { + /* convert checksum errors into IO errors */ + if (error == ECKSUM) + error = EIO; break; + } } zfs_range_unlock(rl); return (error); @@ -1392,6 +1269,7 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr) { minor_t minor = getminor(dev); zvol_state_t *zv; + uint64_t volsize; rl_t *rl; int error = 0; @@ -1402,6 +1280,11 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr) if (zv == NULL) return (ENXIO); + volsize = zv->zv_volsize; + if (uio->uio_resid > 0 && + (uio->uio_loffset < 0 || uio->uio_loffset >= volsize)) + return (EIO); + if (zv->zv_flags & ZVOL_DUMPIFIED) { error = physio(zvol_strategy, NULL, dev, B_WRITE, zvol_minphys, uio); @@ -1410,11 +1293,14 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr) rl = zfs_range_lock(&zv->zv_znode, uio->uio_loffset, uio->uio_resid, RL_WRITER); - while (uio->uio_resid > 0) { + while (uio->uio_resid > 0 && uio->uio_loffset < volsize) { uint64_t bytes = MIN(uio->uio_resid, DMU_MAX_ACCESS >> 1); uint64_t off = uio->uio_loffset; - dmu_tx_t *tx = dmu_tx_create(zv->zv_objset); + + if (bytes > volsize - off) /* don't write past the end */ + bytes = volsize - off; + dmu_tx_hold_write(tx, ZVOL_OBJ, off, bytes); error = dmu_tx_assign(tx, TXG_WAIT); if (error) { @@ -1433,6 +1319,63 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr) return (error); } +int +zvol_getefi(void *arg, int flag, uint64_t vs, uint8_t bs) +{ + struct uuid uuid = EFI_RESERVED; + efi_gpe_t gpe = { 0 }; + uint32_t crc; + dk_efi_t efi; + int length; + char *ptr; + + if (ddi_copyin(arg, &efi, sizeof (dk_efi_t), flag)) + return (EFAULT); + ptr = (char *)(uintptr_t)efi.dki_data_64; + length = efi.dki_length; + /* + * Some clients may attempt to request a PMBR for the + * zvol. Currently this interface will return EINVAL to + * such requests. These requests could be supported by + * adding a check for lba == 0 and consing up an appropriate + * PMBR. + */ + if (efi.dki_lba < 1 || efi.dki_lba > 2 || length <= 0) + return (EINVAL); + + gpe.efi_gpe_StartingLBA = LE_64(34ULL); + gpe.efi_gpe_EndingLBA = LE_64((vs >> bs) - 1); + UUID_LE_CONVERT(gpe.efi_gpe_PartitionTypeGUID, uuid); + + if (efi.dki_lba == 1) { + efi_gpt_t gpt = { 0 }; + + gpt.efi_gpt_Signature = LE_64(EFI_SIGNATURE); + gpt.efi_gpt_Revision = LE_32(EFI_VERSION_CURRENT); + gpt.efi_gpt_HeaderSize = LE_32(sizeof (gpt)); + gpt.efi_gpt_MyLBA = LE_64(1ULL); + gpt.efi_gpt_FirstUsableLBA = LE_64(34ULL); + gpt.efi_gpt_LastUsableLBA = LE_64((vs >> bs) - 1); + gpt.efi_gpt_PartitionEntryLBA = LE_64(2ULL); + gpt.efi_gpt_NumberOfPartitionEntries = LE_32(1); + gpt.efi_gpt_SizeOfPartitionEntry = + LE_32(sizeof (efi_gpe_t)); + CRC32(crc, &gpe, sizeof (gpe), -1U, crc32_table); + gpt.efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc); + CRC32(crc, &gpt, sizeof (gpt), -1U, crc32_table); + gpt.efi_gpt_HeaderCRC32 = LE_32(~crc); + if (ddi_copyout(&gpt, ptr, MIN(sizeof (gpt), length), + flag)) + return (EFAULT); + ptr += sizeof (gpt); + length -= sizeof (gpt); + } + if (length > 0 && ddi_copyout(&gpe, ptr, MIN(sizeof (gpe), + length), flag)) + return (EFAULT); + return (0); +} + /* * Dirtbag ioctls to support mkfs(1M) for UFS filesystems. See dkio(7I). */ @@ -1443,10 +1386,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) zvol_state_t *zv; struct dk_cinfo dki; struct dk_minfo dkm; - dk_efi_t efi; struct dk_callback *dkc; - struct uuid uuid = EFI_RESERVED; - uint32_t crc; int error = 0; rl_t *rl; @@ -1483,77 +1423,14 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) return (error); case DKIOCGETEFI: - if (ddi_copyin((void *)arg, &efi, sizeof (dk_efi_t), flag)) { + { + uint64_t vs = zv->zv_volsize; + uint8_t bs = zv->zv_min_bs; + mutex_exit(&zvol_state_lock); - return (EFAULT); + error = zvol_getefi((void *)arg, flag, vs, bs); + return (error); } - efi.dki_data = (void *)(uintptr_t)efi.dki_data_64; - - /* - * Some clients may attempt to request a PMBR for the - * zvol. Currently this interface will return ENOTTY to - * such requests. These requests could be supported by - * adding a check for lba == 0 and consing up an appropriate - * PMBR. - */ - if (efi.dki_lba == 1) { - efi_gpt_t gpt; - efi_gpe_t gpe; - - bzero(&gpt, sizeof (gpt)); - bzero(&gpe, sizeof (gpe)); - - if (efi.dki_length < sizeof (gpt)) { - mutex_exit(&zvol_state_lock); - return (EINVAL); - } - - gpt.efi_gpt_Signature = LE_64(EFI_SIGNATURE); - gpt.efi_gpt_Revision = LE_32(EFI_VERSION_CURRENT); - gpt.efi_gpt_HeaderSize = LE_32(sizeof (gpt)); - gpt.efi_gpt_FirstUsableLBA = LE_64(34ULL); - gpt.efi_gpt_LastUsableLBA = - LE_64((zv->zv_volsize >> zv->zv_min_bs) - 1); - gpt.efi_gpt_NumberOfPartitionEntries = LE_32(1); - gpt.efi_gpt_PartitionEntryLBA = LE_64(2ULL); - gpt.efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (gpe)); - - UUID_LE_CONVERT(gpe.efi_gpe_PartitionTypeGUID, uuid); - gpe.efi_gpe_StartingLBA = gpt.efi_gpt_FirstUsableLBA; - gpe.efi_gpe_EndingLBA = gpt.efi_gpt_LastUsableLBA; - - CRC32(crc, &gpe, sizeof (gpe), -1U, crc32_table); - gpt.efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc); - - CRC32(crc, &gpt, sizeof (gpt), -1U, crc32_table); - gpt.efi_gpt_HeaderCRC32 = LE_32(~crc); - - mutex_exit(&zvol_state_lock); - if (ddi_copyout(&gpt, efi.dki_data, sizeof (gpt), flag)) - error = EFAULT; - } else if (efi.dki_lba == 2) { - efi_gpe_t gpe; - - bzero(&gpe, sizeof (gpe)); - - if (efi.dki_length < sizeof (gpe)) { - mutex_exit(&zvol_state_lock); - return (EINVAL); - } - - UUID_LE_CONVERT(gpe.efi_gpe_PartitionTypeGUID, uuid); - gpe.efi_gpe_StartingLBA = LE_64(34ULL); - gpe.efi_gpe_EndingLBA = - LE_64((zv->zv_volsize >> zv->zv_min_bs) - 1); - - mutex_exit(&zvol_state_lock); - if (ddi_copyout(&gpe, efi.dki_data, sizeof (gpe), flag)) - error = EFAULT; - } else { - mutex_exit(&zvol_state_lock); - error = EINVAL; - } - return (error); case DKIOCFLUSHWRITECACHE: dkc = (struct dk_callback *)arg; @@ -1646,12 +1523,10 @@ zvol_dump_init(zvol_state_t *zv, boolean_t resize) int error = 0; objset_t *os = zv->zv_objset; nvlist_t *nv = NULL; - uint64_t checksum, compress, refresrv; ASSERT(MUTEX_HELD(&zvol_state_lock)); tx = dmu_tx_create(os); - dmu_tx_hold_free(tx, ZVOL_OBJ, 0, DMU_OBJECT_END); dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL); error = dmu_tx_assign(tx, TXG_WAIT); if (error) { @@ -1670,12 +1545,16 @@ zvol_dump_init(zvol_state_t *zv, boolean_t resize) zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 8, 1, &zv->zv_volsize, tx); } else { + uint64_t checksum, compress, refresrv, vbs; + error = dsl_prop_get_integer(zv->zv_name, zfs_prop_to_name(ZFS_PROP_COMPRESSION), &compress, NULL); error = error ? error : dsl_prop_get_integer(zv->zv_name, zfs_prop_to_name(ZFS_PROP_CHECKSUM), &checksum, NULL); error = error ? error : dsl_prop_get_integer(zv->zv_name, zfs_prop_to_name(ZFS_PROP_REFRESERVATION), &refresrv, NULL); + error = error ? error : dsl_prop_get_integer(zv->zv_name, + zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), &vbs, NULL); error = error ? error : zap_update(os, ZVOL_ZAP_OBJ, zfs_prop_to_name(ZFS_PROP_COMPRESSION), 8, 1, @@ -1685,12 +1564,16 @@ zvol_dump_init(zvol_state_t *zv, boolean_t resize) error = error ? error : zap_update(os, ZVOL_ZAP_OBJ, zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 8, 1, &refresrv, tx); + error = error ? error : zap_update(os, ZVOL_ZAP_OBJ, + zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 8, 1, + &vbs, tx); } dmu_tx_commit(tx); /* Truncate the file */ if (!error) - error = zvol_truncate(zv, 0, DMU_OBJECT_END); + error = dmu_free_long_range(zv->zv_objset, + ZVOL_OBJ, 0, DMU_OBJECT_END); if (error) return (error); @@ -1709,6 +1592,9 @@ zvol_dump_init(zvol_state_t *zv, boolean_t resize) VERIFY(nvlist_add_uint64(nv, zfs_prop_to_name(ZFS_PROP_CHECKSUM), ZIO_CHECKSUM_OFF) == 0); + VERIFY(nvlist_add_uint64(nv, + zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), + SPA_MAXBLOCKSIZE) == 0); error = zfs_set_prop_nvlist(zv->zv_name, nv); nvlist_free(nv); @@ -1788,7 +1674,14 @@ zvol_dump_fini(zvol_state_t *zv) objset_t *os = zv->zv_objset; nvlist_t *nv; int error = 0; - uint64_t checksum, compress, refresrv; + uint64_t checksum, compress, refresrv, vbs; + + /* + * Attempt to restore the zvol back to its pre-dumpified state. + * This is a best-effort attempt as it's possible that not all + * of these properties were initialized during the dumpify process + * (i.e. error during zvol_dump_init). + */ tx = dmu_tx_create(os); dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL); @@ -1797,24 +1690,17 @@ zvol_dump_fini(zvol_state_t *zv) dmu_tx_abort(tx); return (error); } + (void) zap_remove(os, ZVOL_ZAP_OBJ, ZVOL_DUMPSIZE, tx); + dmu_tx_commit(tx); - /* - * Attempt to restore the zvol back to its pre-dumpified state. - * This is a best-effort attempt as it's possible that not all - * of these properties were initialized during the dumpify process - * (i.e. error during zvol_dump_init). - */ (void) zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ, zfs_prop_to_name(ZFS_PROP_CHECKSUM), 8, 1, &checksum); (void) zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ, zfs_prop_to_name(ZFS_PROP_COMPRESSION), 8, 1, &compress); (void) zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ, zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 8, 1, &refresrv); - - (void) zap_remove(os, ZVOL_ZAP_OBJ, ZVOL_DUMPSIZE, tx); - zvol_free_extents(zv); - zv->zv_flags &= ~ZVOL_DUMPIFIED; - dmu_tx_commit(tx); + (void) zap_lookup(zv->zv_objset, ZVOL_ZAP_OBJ, + zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 8, 1, &vbs); VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0); (void) nvlist_add_uint64(nv, @@ -1823,8 +1709,14 @@ zvol_dump_fini(zvol_state_t *zv) zfs_prop_to_name(ZFS_PROP_COMPRESSION), compress); (void) nvlist_add_uint64(nv, zfs_prop_to_name(ZFS_PROP_REFRESERVATION), refresrv); + (void) nvlist_add_uint64(nv, + zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), vbs); (void) zfs_set_prop_nvlist(zv->zv_name, nv); nvlist_free(nv); + zvol_free_extents(zv); + zv->zv_flags &= ~ZVOL_DUMPIFIED; + (void) dmu_free_long_range(os, ZVOL_OBJ, 0, DMU_OBJECT_END); + return (0); } diff --git a/zfs/zcmd/zdb/zdb.c b/zfs/zcmd/zdb/zdb.c index a3b0f1238..253a1346a 100644 --- a/zfs/zcmd/zdb/zdb.c +++ b/zfs/zcmd/zdb/zdb.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zdb.c 1.40 08/04/01 SMI" - #include #include #include @@ -52,6 +50,7 @@ #include #include #include +#include #undef ZFS_MAXNAMELEN #undef verify #include @@ -64,8 +63,6 @@ typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size); extern void dump_intent_log(zilog_t *); uint64_t *zopt_object = NULL; int zopt_objects = 0; -int zdb_advance = ADVANCE_PRE; -zbookmark_t zdb_noread = { 0, 0, ZB_NO_LEVEL, 0 }; libzfs_handle_t *g_zfs; boolean_t zdb_sig_user_data = B_TRUE; int zdb_sig_cksumalg = ZIO_CHECKSUM_SHA256; @@ -90,8 +87,8 @@ static void usage(void) { (void) fprintf(stderr, - "Usage: %s [-udibcsvL] [-U cachefile_path] [-O order] " - "[-B os:obj:level:blkid] [-S user:cksumalg] " + "Usage: %s [-udibcsv] [-U cachefile_path] " + "[-S user:cksumalg] " "dataset [object...]\n" " %s -C [pool]\n" " %s -l dev\n" @@ -111,13 +108,8 @@ usage(void) "dump blkptr signatures\n"); (void) fprintf(stderr, " -v verbose (applies to all others)\n"); (void) fprintf(stderr, " -l dump label contents\n"); - (void) fprintf(stderr, " -L live pool (allows some errors)\n"); - (void) fprintf(stderr, " -O [!] " - "visitation order\n"); (void) fprintf(stderr, " -U cachefile_path -- use alternate " "cachefile\n"); - (void) fprintf(stderr, " -B objset:object:level:blkid -- " - "simulate bad block\n"); (void) fprintf(stderr, " -R read and display block from a " "device\n"); (void) fprintf(stderr, " -e Pool is exported/destroyed/" @@ -140,7 +132,7 @@ fatal(const char *fmt, ...) va_end(ap); (void) fprintf(stderr, "\n"); - exit(1); + abort(); } static void @@ -510,8 +502,7 @@ dump_metaslabs(spa_t *spa) for (c = 0; c < rvd->vdev_children; c++) { vd = rvd->vdev_child[c]; - (void) printf("\n vdev %llu = %s\n\n", - (u_longlong_t)vd->vdev_id, vdev_description(vd)); + (void) printf("\n vdev %llu\n\n", (u_longlong_t)vd->vdev_id); if (dump_opt['d'] <= 5) { (void) printf("\t%10s %10s %5s\n", @@ -536,7 +527,10 @@ dump_dtl(vdev_t *vd, int indent) if (indent == 0) (void) printf("\nDirty time logs:\n\n"); - (void) printf("\t%*s%s\n", indent, "", vdev_description(vd)); + (void) printf("\t%*s%s\n", indent, "", + vd->vdev_path ? vd->vdev_path : + vd->vdev_parent ? vd->vdev_ops->vdev_op_type : + spa_name(vd->vdev_spa)); for (ss = avl_first(t); ss; ss = AVL_NEXT(t, ss)) { /* @@ -571,7 +565,7 @@ dump_dnode(objset_t *os, uint64_t object, void *data, size_t size) } static uint64_t -blkid2offset(dnode_phys_t *dnp, int level, uint64_t blkid) +blkid2offset(const dnode_phys_t *dnp, int level, uint64_t blkid) { if (level < 0) return (blkid); @@ -602,115 +596,104 @@ sprintf_blkptr_compact(char *blkbuf, blkptr_t *bp, int alldvas) (u_longlong_t)bp->blk_birth); } -/* ARGSUSED */ -static int -zdb_indirect_cb(traverse_blk_cache_t *bc, spa_t *spa, void *a) +static void +print_indirect(blkptr_t *bp, const zbookmark_t *zb, + const dnode_phys_t *dnp) { - zbookmark_t *zb = &bc->bc_bookmark; - blkptr_t *bp = &bc->bc_blkptr; - void *data = bc->bc_data; - dnode_phys_t *dnp = bc->bc_dnode; - char blkbuf[BP_SPRINTF_LEN + 80]; + char blkbuf[BP_SPRINTF_LEN]; int l; - if (bc->bc_errno) { - (void) sprintf(blkbuf, - "Error %d reading <%llu, %llu, %lld, %llu>: ", - bc->bc_errno, - (u_longlong_t)zb->zb_objset, - (u_longlong_t)zb->zb_object, - (u_longlong_t)zb->zb_level, - (u_longlong_t)zb->zb_blkid); - goto out; - } + ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type); + ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level); - if (zb->zb_level == -1) { - ASSERT3U(BP_GET_TYPE(bp), ==, DMU_OT_OBJSET); - ASSERT3U(BP_GET_LEVEL(bp), ==, 0); - } else { - ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type); - ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level); - } - - if (zb->zb_level > 0) { - uint64_t fill = 0; - blkptr_t *bpx, *bpend; - - for (bpx = data, bpend = bpx + BP_GET_LSIZE(bp) / sizeof (*bpx); - bpx < bpend; bpx++) { - if (bpx->blk_birth != 0) { - fill += bpx->blk_fill; - } else { - ASSERT(bpx->blk_fill == 0); - } - } - ASSERT3U(fill, ==, bp->blk_fill); - } - - if (zb->zb_level == 0 && dnp->dn_type == DMU_OT_DNODE) { - uint64_t fill = 0; - dnode_phys_t *dnx, *dnend; - - for (dnx = data, dnend = dnx + (BP_GET_LSIZE(bp)>>DNODE_SHIFT); - dnx < dnend; dnx++) { - if (dnx->dn_type != DMU_OT_NONE) - fill++; - } - ASSERT3U(fill, ==, bp->blk_fill); - } - - (void) sprintf(blkbuf, "%16llx ", + (void) printf("%16llx ", (u_longlong_t)blkid2offset(dnp, zb->zb_level, zb->zb_blkid)); ASSERT(zb->zb_level >= 0); for (l = dnp->dn_nlevels - 1; l >= -1; l--) { if (l == zb->zb_level) { - (void) sprintf(blkbuf + strlen(blkbuf), "L%llx", - (u_longlong_t)zb->zb_level); + (void) printf("L%llx", (u_longlong_t)zb->zb_level); } else { - (void) sprintf(blkbuf + strlen(blkbuf), " "); + (void) printf(" "); } } -out: - if (bp->blk_birth == 0) { - (void) sprintf(blkbuf + strlen(blkbuf), ""); - (void) printf("%s\n", blkbuf); - } else { - sprintf_blkptr_compact(blkbuf + strlen(blkbuf), bp, - dump_opt['d'] > 5 ? 1 : 0); - (void) printf("%s\n", blkbuf); + sprintf_blkptr_compact(blkbuf, bp, dump_opt['d'] > 5 ? 1 : 0); + (void) printf("%s\n", blkbuf); +} + +#define SET_BOOKMARK(zb, objset, object, level, blkid) \ +{ \ + (zb)->zb_objset = objset; \ + (zb)->zb_object = object; \ + (zb)->zb_level = level; \ + (zb)->zb_blkid = blkid; \ +} + +static int +visit_indirect(spa_t *spa, const dnode_phys_t *dnp, + blkptr_t *bp, const zbookmark_t *zb) +{ + int err; + + if (bp->blk_birth == 0) + return (0); + + print_indirect(bp, zb, dnp); + + if (BP_GET_LEVEL(bp) > 0) { + uint32_t flags = ARC_WAIT; + int i; + blkptr_t *cbp; + int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT; + arc_buf_t *buf; + uint64_t fill = 0; + + err = arc_read_nolock(NULL, spa, bp, arc_getbuf_func, &buf, + ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); + if (err) + return (err); + + /* recursively visit blocks below this */ + cbp = buf->b_data; + for (i = 0; i < epb; i++, cbp++) { + zbookmark_t czb; + + SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object, + zb->zb_level - 1, + zb->zb_blkid * epb + i); + err = visit_indirect(spa, dnp, cbp, &czb); + if (err) + break; + fill += cbp->blk_fill; + } + ASSERT3U(fill, ==, bp->blk_fill); + (void) arc_buf_remove_ref(buf, &buf); } - return (bc->bc_errno ? ERESTART : 0); + return (err); } /*ARGSUSED*/ static void -dump_indirect(objset_t *os, uint64_t object, void *data, size_t size) +dump_indirect(dnode_t *dn) { - traverse_handle_t *th; - uint64_t objset = dmu_objset_id(os); - int advance = zdb_advance; + dnode_phys_t *dnp = dn->dn_phys; + int j; + zbookmark_t czb; (void) printf("Indirect blocks:\n"); - if (object == 0) - advance |= ADVANCE_DATA; - - th = traverse_init(dmu_objset_spa(os), zdb_indirect_cb, NULL, advance, - ZIO_FLAG_CANFAIL); - th->th_noread = zdb_noread; - - traverse_add_dnode(th, 0, -1ULL, objset, object); - - while (traverse_more(th) == EAGAIN) - continue; + SET_BOOKMARK(&czb, dmu_objset_id(&dn->dn_objset->os), + dn->dn_object, dnp->dn_nlevels - 1, 0); + for (j = 0; j < dnp->dn_nblkptr; j++) { + czb.zb_blkid = j; + (void) visit_indirect(dmu_objset_spa(&dn->dn_objset->os), dnp, + &dnp->dn_blkptr[j], &czb); + } (void) printf("\n"); - - traverse_fini(th); } /*ARGSUSED*/ @@ -719,7 +702,7 @@ dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size) { dsl_dir_phys_t *dd = data; time_t crtime; - char used[6], compressed[6], uncompressed[6], quota[6], resv[6]; + char nice[6]; if (dd == NULL) return; @@ -727,12 +710,6 @@ dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size) ASSERT3U(size, >=, sizeof (dsl_dir_phys_t)); crtime = dd->dd_creation_time; - nicenum(dd->dd_used_bytes, used); - nicenum(dd->dd_compressed_bytes, compressed); - nicenum(dd->dd_uncompressed_bytes, uncompressed); - nicenum(dd->dd_quota, quota); - nicenum(dd->dd_reserved, resv); - (void) printf("\t\tcreation_time = %s", ctime(&crtime)); (void) printf("\t\thead_dataset_obj = %llu\n", (u_longlong_t)dd->dd_head_dataset_obj); @@ -742,15 +719,32 @@ dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size) (u_longlong_t)dd->dd_origin_obj); (void) printf("\t\tchild_dir_zapobj = %llu\n", (u_longlong_t)dd->dd_child_dir_zapobj); - (void) printf("\t\tused_bytes = %s\n", used); - (void) printf("\t\tcompressed_bytes = %s\n", compressed); - (void) printf("\t\tuncompressed_bytes = %s\n", uncompressed); - (void) printf("\t\tquota = %s\n", quota); - (void) printf("\t\treserved = %s\n", resv); + nicenum(dd->dd_used_bytes, nice); + (void) printf("\t\tused_bytes = %s\n", nice); + nicenum(dd->dd_compressed_bytes, nice); + (void) printf("\t\tcompressed_bytes = %s\n", nice); + nicenum(dd->dd_uncompressed_bytes, nice); + (void) printf("\t\tuncompressed_bytes = %s\n", nice); + nicenum(dd->dd_quota, nice); + (void) printf("\t\tquota = %s\n", nice); + nicenum(dd->dd_reserved, nice); + (void) printf("\t\treserved = %s\n", nice); (void) printf("\t\tprops_zapobj = %llu\n", (u_longlong_t)dd->dd_props_zapobj); (void) printf("\t\tdeleg_zapobj = %llu\n", (u_longlong_t)dd->dd_deleg_zapobj); + (void) printf("\t\tflags = %llx\n", + (u_longlong_t)dd->dd_flags); + +#define DO(which) \ + nicenum(dd->dd_used_breakdown[DD_USED_ ## which], nice); \ + (void) printf("\t\tused_breakdown[" #which "] = %s\n", nice) + DO(HEAD); + DO(SNAP); + DO(CHILD); + DO(CHILD_RSRV); + DO(REFRSRV); +#undef DO } /*ARGSUSED*/ @@ -773,7 +767,7 @@ dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size) nicenum(ds->ds_unique_bytes, unique); sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, &ds->ds_bp); - (void) printf("\t\tdataset_obj = %llu\n", + (void) printf("\t\tdir_obj = %llu\n", (u_longlong_t)ds->ds_dir_obj); (void) printf("\t\tprev_snap_obj = %llu\n", (u_longlong_t)ds->ds_prev_snap_obj); @@ -800,6 +794,10 @@ dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size) (u_longlong_t)ds->ds_guid); (void) printf("\t\tflags = %llx\n", (u_longlong_t)ds->ds_flags); + (void) printf("\t\tnext_clones_obj = %llu\n", + (u_longlong_t)ds->ds_next_clones_obj); + (void) printf("\t\tprops_obj = %llu\n", + (u_longlong_t)ds->ds_props_obj); (void) printf("\t\tbp = %s\n", blkbuf); } @@ -1007,6 +1005,8 @@ static object_viewer_t *object_viewer[DMU_OT_NUMTYPES] = { dump_uint8, /* ZFS SYSACL */ dump_none, /* FUID nvlist */ dump_packed_nvlist, /* FUID nvlist size */ + dump_zap, /* DSL dataset next clones */ + dump_zap, /* DSL scrub queue */ }; static void @@ -1076,7 +1076,7 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) } if (verbosity >= 5) - dump_indirect(os, object, NULL, 0); + dump_indirect(dn); if (verbosity >= 5) { /* @@ -1093,13 +1093,13 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) } for (;;) { - error = dnode_next_offset(dn, B_FALSE, &start, minlvl, - blkfill, 0); + error = dnode_next_offset(dn, + 0, &start, minlvl, blkfill, 0); if (error) break; end = start; - error = dnode_next_offset(dn, B_TRUE, &end, minlvl, - blkfill, 0); + error = dnode_next_offset(dn, + DNODE_FIND_HOLE, &end, minlvl, blkfill, 0); nicenum(end - start, segsize); (void) printf("\t\tsegment [%016llx, %016llx)" " size %5s\n", (u_longlong_t)start, @@ -1139,8 +1139,8 @@ dump_dir(objset_t *os) if (dds.dds_type == DMU_OST_META) { dds.dds_creation_txg = TXG_INITIAL; usedobjs = os->os->os_rootbp->blk_fill; - refdbytes = - os->os->os_spa->spa_dsl_pool->dp_mos_dir->dd_used_bytes; + refdbytes = os->os->os_spa->spa_dsl_pool-> + dp_mos_dir->dd_phys->dd_used_bytes; } else { dmu_objset_space(os, &refdbytes, &scratch, &usedobjs, &scratch); } @@ -1174,6 +1174,9 @@ dump_dir(objset_t *os) if (verbosity < 2) return; + if (os->os->os_rootbp->blk_birth == 0) + return; + if (zopt_objects != 0) { for (i = 0; i < zopt_objects; i++) dump_object(os, zopt_object[i], verbosity, @@ -1234,6 +1237,52 @@ dump_config(const char *pool) mutex_exit(&spa_namespace_lock); } +static void +dump_cachefile(const char *cachefile) +{ + int fd; + struct stat64 statbuf; + char *buf; + nvlist_t *config; + + if ((fd = open64(cachefile, O_RDONLY)) < 0) { + (void) printf("cannot open '%s': %s\n", cachefile, + strerror(errno)); + exit(1); + } + + if (fstat64(fd, &statbuf) != 0) { + (void) printf("failed to stat '%s': %s\n", cachefile, + strerror(errno)); + exit(1); + } + + if ((buf = malloc(statbuf.st_size)) == NULL) { + (void) fprintf(stderr, "failed to allocate %llu bytes\n", + (u_longlong_t)statbuf.st_size); + exit(1); + } + + if (read(fd, buf, statbuf.st_size) != statbuf.st_size) { + (void) fprintf(stderr, "failed to read %llu bytes\n", + (u_longlong_t)statbuf.st_size); + exit(1); + } + + (void) close(fd); + + if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) { + (void) fprintf(stderr, "failed to unpack nvlist\n"); + exit(1); + } + + free(buf); + + dump_nvlist(config, 0); + + nvlist_free(config); +} + static void dump_label(const char *dev) { @@ -1290,7 +1339,7 @@ dump_one_dir(char *dsname, void *arg) objset_t *os; error = dmu_objset_open(dsname, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &os); + DS_MODE_USER | DS_MODE_READONLY, &os); if (error) { (void) printf("Could not open %s\n", dsname); return (0); @@ -1301,160 +1350,73 @@ dump_one_dir(char *dsname, void *arg) return (0); } -static void -zdb_space_map_load(spa_t *spa) -{ - vdev_t *rvd = spa->spa_root_vdev; - vdev_t *vd; - int c, m, error; - - for (c = 0; c < rvd->vdev_children; c++) { - vd = rvd->vdev_child[c]; - for (m = 0; m < vd->vdev_ms_count; m++) { - metaslab_t *msp = vd->vdev_ms[m]; - mutex_enter(&msp->ms_lock); - error = space_map_load(&msp->ms_allocmap[0], NULL, - SM_ALLOC, &msp->ms_smo, spa->spa_meta_objset); - mutex_exit(&msp->ms_lock); - if (error) - fatal("%s bad space map #%d, error %d", - spa->spa_name, c, error); - } - } -} - -static int -zdb_space_map_claim(spa_t *spa, blkptr_t *bp, zbookmark_t *zb) -{ - dva_t *dva = bp->blk_dva; - vdev_t *vd; - metaslab_t *msp; - space_map_t *allocmap, *freemap; - int error; - int d; - blkptr_t blk = *bp; - - for (d = 0; d < BP_GET_NDVAS(bp); d++) { - uint64_t vdev = DVA_GET_VDEV(&dva[d]); - uint64_t offset = DVA_GET_OFFSET(&dva[d]); - uint64_t size = DVA_GET_ASIZE(&dva[d]); - - if ((vd = vdev_lookup_top(spa, vdev)) == NULL) - return (ENXIO); - - if ((offset >> vd->vdev_ms_shift) >= vd->vdev_ms_count) - return (ENXIO); - - msp = vd->vdev_ms[offset >> vd->vdev_ms_shift]; - allocmap = &msp->ms_allocmap[0]; - freemap = &msp->ms_freemap[0]; - - /* Prepare our copy of the bp in case we need to read GBHs */ - if (DVA_GET_GANG(&dva[d])) { - size = vdev_psize_to_asize(vd, SPA_GANGBLOCKSIZE); - DVA_SET_ASIZE(&blk.blk_dva[d], size); - DVA_SET_GANG(&blk.blk_dva[d], 0); - } - - mutex_enter(&msp->ms_lock); - if (space_map_contains(freemap, offset, size)) { - mutex_exit(&msp->ms_lock); - return (EAGAIN); /* allocated more than once */ - } - - if (!space_map_contains(allocmap, offset, size)) { - mutex_exit(&msp->ms_lock); - return (ESTALE); /* not allocated at all */ - } - - space_map_remove(allocmap, offset, size); - space_map_add(freemap, offset, size); - - mutex_exit(&msp->ms_lock); - } - - if (BP_IS_GANG(bp)) { - zio_gbh_phys_t gbh; - int g; - - /* LINTED - compile time assert */ - ASSERT(sizeof (zio_gbh_phys_t) == SPA_GANGBLOCKSIZE); - - BP_SET_CHECKSUM(&blk, ZIO_CHECKSUM_GANG_HEADER); - BP_SET_PSIZE(&blk, SPA_GANGBLOCKSIZE); - BP_SET_LSIZE(&blk, SPA_GANGBLOCKSIZE); - BP_SET_COMPRESS(&blk, ZIO_COMPRESS_OFF); - error = zio_wait(zio_read(NULL, spa, &blk, &gbh, - SPA_GANGBLOCKSIZE, NULL, NULL, ZIO_PRIORITY_SYNC_READ, - ZIO_FLAG_CANFAIL | ZIO_FLAG_CONFIG_HELD, zb)); - if (error) - return (error); - if (BP_SHOULD_BYTESWAP(&blk)) - byteswap_uint64_array(&gbh, SPA_GANGBLOCKSIZE); - for (g = 0; g < SPA_GBH_NBLKPTRS; g++) { - if (BP_IS_HOLE(&gbh.zg_blkptr[g])) - break; - error = zdb_space_map_claim(spa, &gbh.zg_blkptr[g], zb); - if (error) - return (error); - } - } - - return (0); -} - static void zdb_leak(space_map_t *sm, uint64_t start, uint64_t size) { - metaslab_t *msp; - - /* LINTED */ - msp = (metaslab_t *)((char *)sm - offsetof(metaslab_t, ms_allocmap[0])); + vdev_t *vd = sm->sm_ppd; (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n", - (u_longlong_t)msp->ms_group->mg_vd->vdev_id, - (u_longlong_t)start, - (u_longlong_t)size); + (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size); +} + +/* ARGSUSED */ +static void +zdb_space_map_load(space_map_t *sm) +{ } static void -zdb_space_map_unload(spa_t *spa) +zdb_space_map_unload(space_map_t *sm) +{ + space_map_vacate(sm, zdb_leak, sm); +} + +/* ARGSUSED */ +static void +zdb_space_map_claim(space_map_t *sm, uint64_t start, uint64_t size) +{ +} + +static space_map_ops_t zdb_space_map_ops = { + zdb_space_map_load, + zdb_space_map_unload, + NULL, /* alloc */ + zdb_space_map_claim, + NULL /* free */ +}; + +static void +zdb_leak_init(spa_t *spa) { vdev_t *rvd = spa->spa_root_vdev; - vdev_t *vd; - int c, m; - for (c = 0; c < rvd->vdev_children; c++) { - vd = rvd->vdev_child[c]; - for (m = 0; m < vd->vdev_ms_count; m++) { + for (int c = 0; c < rvd->vdev_children; c++) { + vdev_t *vd = rvd->vdev_child[c]; + for (int m = 0; m < vd->vdev_ms_count; m++) { metaslab_t *msp = vd->vdev_ms[m]; mutex_enter(&msp->ms_lock); - space_map_vacate(&msp->ms_allocmap[0], zdb_leak, - &msp->ms_allocmap[0]); - space_map_unload(&msp->ms_allocmap[0]); - space_map_vacate(&msp->ms_freemap[0], NULL, NULL); + VERIFY(space_map_load(&msp->ms_map, &zdb_space_map_ops, + SM_ALLOC, &msp->ms_smo, spa->spa_meta_objset) == 0); + msp->ms_map.sm_ppd = vd; mutex_exit(&msp->ms_lock); } } } static void -zdb_refresh_ubsync(spa_t *spa) +zdb_leak_fini(spa_t *spa) { - uberblock_t ub = { 0 }; vdev_t *rvd = spa->spa_root_vdev; - zio_t *zio; - /* - * Reload the uberblock. - */ - zio = zio_root(spa, NULL, NULL, - ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE); - vdev_uberblock_load(zio, rvd, &ub); - (void) zio_wait(zio); - - if (ub.ub_txg != 0) - spa->spa_ubsync = ub; + for (int c = 0; c < rvd->vdev_children; c++) { + vdev_t *vd = rvd->vdev_child[c]; + for (int m = 0; m < vd->vdev_ms_count; m++) { + metaslab_t *msp = vd->vdev_ms[m]; + mutex_enter(&msp->ms_lock); + space_map_unload(&msp->ms_map); + mutex_exit(&msp->ms_lock); + } + } } /* @@ -1471,22 +1433,19 @@ typedef struct zdb_blkstats { #define DMU_OT_DEFERRED DMU_OT_NONE #define DMU_OT_TOTAL DMU_OT_NUMTYPES -#define ZB_TOTAL ZB_MAXLEVEL +#define ZB_TOTAL DN_MAX_LEVELS typedef struct zdb_cb { zdb_blkstats_t zcb_type[ZB_TOTAL + 1][DMU_OT_TOTAL + 1]; uint64_t zcb_errors[256]; - traverse_blk_cache_t *zcb_cache; int zcb_readfails; int zcb_haderrors; } zdb_cb_t; static void -zdb_count_block(spa_t *spa, zdb_cb_t *zcb, blkptr_t *bp, int type) +zdb_count_block(spa_t *spa, zdb_cb_t *zcb, blkptr_t *bp, dmu_object_type_t type) { - int i, error; - - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { int l = (i < 2) ? BP_GET_LEVEL(bp) : ZB_TOTAL; int t = (i & 1) ? type : DMU_OT_TOTAL; zdb_blkstats_t *zb = &zcb->zcb_type[l][t]; @@ -1500,7 +1459,7 @@ zdb_count_block(spa_t *spa, zdb_cb_t *zcb, blkptr_t *bp, int type) if (dump_opt['S']) { boolean_t print_sig; - print_sig = !zdb_sig_user_data || (BP_GET_LEVEL(bp) == 0 && + print_sig = !zdb_sig_user_data || (BP_GET_LEVEL(bp) == 0 && BP_GET_TYPE(bp) == DMU_OT_PLAIN_FILE_CONTENTS); if (BP_GET_CHECKSUM(bp) < zdb_sig_cksumalg) @@ -1522,100 +1481,80 @@ zdb_count_block(spa_t *spa, zdb_cb_t *zcb, blkptr_t *bp, int type) } } - if (dump_opt['L']) - return; - - error = zdb_space_map_claim(spa, bp, &zcb->zcb_cache->bc_bookmark); - - if (error == 0) - return; - - if (error == EAGAIN) - (void) fatal("double-allocation, bp=%p", bp); - - if (error == ESTALE) - (void) fatal("reference to freed block, bp=%p", bp); - - (void) fatal("fatal error %d in bp %p", error, bp); + VERIFY(zio_wait(zio_claim(NULL, spa, spa_first_txg(spa), bp, + NULL, NULL, ZIO_FLAG_MUSTSUCCEED)) == 0); } static int -zdb_blkptr_cb(traverse_blk_cache_t *bc, spa_t *spa, void *arg) +zdb_blkptr_cb(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb, + const dnode_phys_t *dnp, void *arg) { - zbookmark_t *zb = &bc->bc_bookmark; zdb_cb_t *zcb = arg; - blkptr_t *bp = &bc->bc_blkptr; - dmu_object_type_t type = BP_GET_TYPE(bp); char blkbuf[BP_SPRINTF_LEN]; - int error = 0; - if (bc->bc_errno) { - if (zcb->zcb_readfails++ < 10 && dump_opt['L']) { - zdb_refresh_ubsync(spa); - error = EAGAIN; - } else { + if (bp == NULL) + return (0); + + zdb_count_block(spa, zcb, bp, BP_GET_TYPE(bp)); + + if (dump_opt['c'] || dump_opt['S']) { + int ioerr, size; + void *data; + + size = BP_GET_LSIZE(bp); + data = malloc(size); + ioerr = zio_wait(zio_read(NULL, spa, bp, data, size, + NULL, NULL, ZIO_PRIORITY_ASYNC_READ, + ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB, zb)); + free(data); + + /* We expect io errors on intent log */ + if (ioerr && BP_GET_TYPE(bp) != DMU_OT_INTENT_LOG) { zcb->zcb_haderrors = 1; - zcb->zcb_errors[bc->bc_errno]++; - error = ERESTART; + zcb->zcb_errors[ioerr]++; + + if (dump_opt['b'] >= 2) + sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, bp); + else + blkbuf[0] = '\0'; + + if (!dump_opt['S']) { + (void) printf("zdb_blkptr_cb: " + "Got error %d reading " + "<%llu, %llu, %lld, %llx> %s -- skipping\n", + ioerr, + (u_longlong_t)zb->zb_objset, + (u_longlong_t)zb->zb_object, + (u_longlong_t)zb->zb_level, + (u_longlong_t)zb->zb_blkid, + blkbuf); + } } - - if (dump_opt['b'] >= 3 || (dump_opt['b'] >= 2 && bc->bc_errno)) - sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, bp); - else - blkbuf[0] = '\0'; - - if (!dump_opt['S']) { - (void) printf("zdb_blkptr_cb: Got error %d reading " - "<%llu, %llu, %lld, %llx> %s -- %s\n", - bc->bc_errno, - (u_longlong_t)zb->zb_objset, - (u_longlong_t)zb->zb_object, - (u_longlong_t)zb->zb_level, - (u_longlong_t)zb->zb_blkid, - blkbuf, - error == EAGAIN ? "retrying" : "skipping"); - } - - return (error); } zcb->zcb_readfails = 0; - ASSERT(!BP_IS_HOLE(bp)); - if (dump_opt['b'] >= 4) { sprintf_blkptr(blkbuf, BP_SPRINTF_LEN, bp); (void) printf("objset %llu object %llu offset 0x%llx %s\n", (u_longlong_t)zb->zb_objset, (u_longlong_t)zb->zb_object, - (u_longlong_t)blkid2offset(bc->bc_dnode, - zb->zb_level, zb->zb_blkid), blkbuf); + (u_longlong_t)blkid2offset(dnp, zb->zb_level, zb->zb_blkid), + blkbuf); } - zdb_count_block(spa, zcb, bp, type); - return (0); } static int dump_block_stats(spa_t *spa) { - traverse_handle_t *th; zdb_cb_t zcb = { 0 }; - traverse_blk_cache_t dummy_cache = { 0 }; zdb_blkstats_t *zb, *tzb; uint64_t alloc, space, logalloc; vdev_t *rvd = spa->spa_root_vdev; int leaks = 0; - int advance = zdb_advance; - int c, e, flags; - - zcb.zcb_cache = &dummy_cache; - - if (dump_opt['c'] || dump_opt['S']) - advance |= ADVANCE_DATA; - - advance |= ADVANCE_PRUNE | ADVANCE_ZIL; + int c, e; if (!dump_opt['S']) { (void) printf("\nTraversing all blocks to %sverify" @@ -1624,14 +1563,14 @@ dump_block_stats(spa_t *spa) } /* - * Load all space maps. As we traverse the pool, if we find a block - * that's not in its space map, that indicates a double-allocation, - * reference to a freed block, or an unclaimed block. Otherwise we - * remove the block from the space map. If the space maps are not - * empty when we're done, that indicates leaked blocks. + * Load all space maps as SM_ALLOC maps, then traverse the pool + * claiming each block we discover. If the pool is perfectly + * consistent, the space maps will be empty when we're done. + * Anything left over is a leak; any block we can't claim (because + * it's not part of any space map) is a double allocation, + * reference to a freed block, or an unclaimed log block. */ - if (!dump_opt['L']) - zdb_space_map_load(spa); + zdb_leak_init(spa); /* * If there's a deferred-free bplist, process that first. @@ -1657,22 +1596,7 @@ dump_block_stats(spa_t *spa) bplist_close(bpl); } - /* - * Now traverse the pool. If we're reading all data to verify - * checksums, do a scrubbing read so that we validate all copies. - */ - flags = ZIO_FLAG_CANFAIL; - if (advance & ADVANCE_DATA) - flags |= ZIO_FLAG_SCRUB; - th = traverse_init(spa, zdb_blkptr_cb, &zcb, advance, flags); - th->th_noread = zdb_noread; - - traverse_add_pool(th, 0, spa_first_txg(spa) + TXG_CONCURRENT_STATES); - - while (traverse_more(th) == EAGAIN) - continue; - - traverse_fini(th); + zcb.zcb_haderrors |= traverse_pool(spa, zdb_blkptr_cb, &zcb); if (zcb.zcb_haderrors && !dump_opt['S']) { (void) printf("\nError counts:\n\n"); @@ -1688,8 +1612,7 @@ dump_block_stats(spa_t *spa) /* * Report any leaked segments. */ - if (!dump_opt['L']) - zdb_space_map_unload(spa); + zdb_leak_fini(spa); /* * If we're interested in printing out the blkptr signatures, @@ -1699,10 +1622,6 @@ dump_block_stats(spa_t *spa) if (dump_opt['S']) return (zcb.zcb_haderrors ? 3 : 0); - if (dump_opt['L']) - (void) printf("\n\n *** Live pool traversal; " - "block counts are only approximate ***\n\n"); - alloc = spa_get_alloc(spa); space = spa_get_space(spa); @@ -1830,8 +1749,6 @@ dump_zpool(spa_t *spa) dsl_pool_t *dp = spa_get_dsl(spa); int rc = 0; - spa_config_enter(spa, RW_READER, FTAG); - if (dump_opt['u']) dump_uberblock(&spa->spa_uberblock); @@ -1843,7 +1760,7 @@ dump_zpool(spa_t *spa) dump_dtl(spa->spa_root_vdev, 0); dump_metaslabs(spa); } - (void) dmu_objset_find(spa->spa_name, dump_one_dir, NULL, + (void) dmu_objset_find(spa_name(spa), dump_one_dir, NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN); } @@ -1853,8 +1770,6 @@ dump_zpool(spa_t *spa) if (dump_opt['s']) show_pool_stats(spa); - spa_config_exit(spa, FTAG); - if (rc != 0) exit(rc); } @@ -2061,12 +1976,12 @@ zdb_read_block(char *thing, spa_t **spap) zio_t *zio; vdev_t *vd; void *buf; - char *s, *p, *dup, *spa_name, *vdev, *flagstr; + char *s, *p, *dup, *pool, *vdev, *flagstr; int i, error, zio_flags; dup = strdup(thing); s = strtok(dup, ":"); - spa_name = s ? s : ""; + pool = s ? s : ""; s = strtok(NULL, ":"); vdev = s ? s : ""; s = strtok(NULL, ":"); @@ -2116,14 +2031,13 @@ zdb_read_block(char *thing, spa_t **spap) } } - if (spa == NULL || spa->spa_name == NULL || - strcmp(spa->spa_name, spa_name)) { - if (spa && spa->spa_name) + if (spa == NULL || strcmp(spa_name(spa), pool) != 0) { + if (spa) spa_close(spa, (void *)zdb_read_block); - error = spa_open(spa_name, spap, (void *)zdb_read_block); + error = spa_open(pool, spap, (void *)zdb_read_block); if (error) fatal("Failed to open pool '%s': %s", - spa_name, strerror(error)); + pool, strerror(error)); spa = *spap; } @@ -2143,16 +2057,15 @@ zdb_read_block(char *thing, spa_t **spap) buf = umem_alloc(size, UMEM_NOFAIL); zio_flags = ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE | - ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY | ZIO_FLAG_NOBOOKMARK; - - if (flags & ZDB_FLAG_PHYS) - zio_flags |= ZIO_FLAG_PHYSICAL; + ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY; + spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); zio = zio_root(spa, NULL, NULL, 0); /* XXX todo - cons up a BP so RAID-Z will be happy */ zio_nowait(zio_vdev_child_io(zio, NULL, vd, offset, buf, size, ZIO_TYPE_READ, ZIO_PRIORITY_SYNC_READ, zio_flags, NULL, NULL)); error = zio_wait(zio); + spa_config_exit(spa, SCL_STATE, FTAG); if (error) { (void) printf("Read of %s failed, error: %d\n", thing, error); @@ -2182,7 +2095,9 @@ nvlist_string_match(nvlist_t *config, char *name, char *tgt) { char *s; - verify(nvlist_lookup_string(config, name, &s) == 0); + if (nvlist_lookup_string(config, name, &s) != 0) + return (B_FALSE); + return (strcmp(s, tgt) == 0); } @@ -2191,7 +2106,9 @@ nvlist_uint64_match(nvlist_t *config, char *name, uint64_t tgt) { uint64_t val; - verify(nvlist_lookup_uint64(config, name, &val) == 0); + if (nvlist_lookup_uint64(config, name, &val) != 0) + return (B_FALSE); + return (val == tgt); } @@ -2265,19 +2182,16 @@ pool_match(nvlist_t *config, char *tgt) } static int -find_exported_zpool(char *pool_id, nvlist_t **configp, char *vdev_dir, - char *cachefile) +find_exported_zpool(char *pool_id, nvlist_t **configp, char *vdev_dir) { nvlist_t *pools; int error = ENOENT; nvlist_t *match = NULL; if (vdev_dir != NULL) - pools = zpool_find_import(g_zfs, 1, &vdev_dir, B_TRUE); - else if (cachefile != NULL) - pools = zpool_find_import_cached(g_zfs, cachefile, B_TRUE); + pools = zpool_find_import_activeok(g_zfs, 1, &vdev_dir); else - pools = zpool_find_import(g_zfs, 0, NULL, B_TRUE); + pools = zpool_find_import_activeok(g_zfs, 0, NULL); if (pools != NULL) { nvpair_t *elem = NULL; @@ -2313,17 +2227,15 @@ main(int argc, char **argv) int dump_all = 1; int verbose = 0; int error; - int flag, set; int exported = 0; char *vdev_dir = NULL; - char *cachefile = NULL; (void) setrlimit(RLIMIT_NOFILE, &rl); (void) enable_extended_FILE_stdio(-1, -1); dprintf_setup(&argc, argv); - while ((c = getopt(argc, argv, "udibcsvCLO:B:S:U:lRep:")) != -1) { + while ((c = getopt(argc, argv, "udibcsvCS:U:lRep:")) != -1) { switch (c) { case 'u': case 'd': @@ -2337,54 +2249,11 @@ main(int argc, char **argv) dump_opt[c]++; dump_all = 0; break; - case 'L': - dump_opt[c]++; - break; - case 'O': - endstr = optarg; - if (endstr[0] == '!') { - endstr++; - set = 0; - } else { - set = 1; - } - if (strcmp(endstr, "post") == 0) { - flag = ADVANCE_PRE; - set = !set; - } else if (strcmp(endstr, "pre") == 0) { - flag = ADVANCE_PRE; - } else if (strcmp(endstr, "prune") == 0) { - flag = ADVANCE_PRUNE; - } else if (strcmp(endstr, "data") == 0) { - flag = ADVANCE_DATA; - } else if (strcmp(endstr, "holes") == 0) { - flag = ADVANCE_HOLES; - } else { - usage(); - } - if (set) - zdb_advance |= flag; - else - zdb_advance &= ~flag; - break; - case 'B': - endstr = optarg - 1; - zdb_noread.zb_objset = strtoull(endstr + 1, &endstr, 0); - zdb_noread.zb_object = strtoull(endstr + 1, &endstr, 0); - zdb_noread.zb_level = strtol(endstr + 1, &endstr, 0); - zdb_noread.zb_blkid = strtoull(endstr + 1, &endstr, 16); - (void) printf("simulating bad block " - "<%llu, %llu, %lld, %llx>\n", - (u_longlong_t)zdb_noread.zb_objset, - (u_longlong_t)zdb_noread.zb_object, - (u_longlong_t)zdb_noread.zb_level, - (u_longlong_t)zdb_noread.zb_blkid); - break; case 'v': verbose++; break; case 'U': - cachefile = optarg; + spa_config_path = optarg; break; case 'e': exported = 1; @@ -2416,21 +2285,17 @@ main(int argc, char **argv) } } - if (vdev_dir != NULL && exported == 0) - (void) fatal("-p option requires use of -e\n"); + if (vdev_dir != NULL && exported == 0) { + (void) fprintf(stderr, "-p option requires use of -e\n"); + usage(); + } kernel_init(FREAD); g_zfs = libzfs_init(); ASSERT(g_zfs != NULL); - /* - * Disable vdev caching. If we don't do this, live pool traversal - * won't make progress because it will never see disk updates. - */ - zfs_vdev_cache_size = 0; - for (c = 0; c < 256; c++) { - if (dump_all && c != 'L' && c != 'l' && c != 'R') + if (dump_all && c != 'l' && c != 'R') dump_opt[c] = 1; if (dump_opt[c]) dump_opt[c] += verbose; @@ -2441,7 +2306,7 @@ main(int argc, char **argv) if (argc < 1) { if (dump_opt['C']) { - dump_config(NULL); + dump_cachefile(spa_config_path); return (0); } usage(); @@ -2476,21 +2341,18 @@ main(int argc, char **argv) if (dump_opt['C']) dump_config(argv[0]); - if (exported == 0 && cachefile == NULL) { - if (strchr(argv[0], '/') != NULL) { - error = dmu_objset_open(argv[0], DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &os); - } else { - error = spa_open(argv[0], &spa, FTAG); - } - } else { + error = 0; + if (exported) { /* * Check to see if the name refers to an exported zpool */ + char *slash; nvlist_t *exported_conf = NULL; - error = find_exported_zpool(argv[0], &exported_conf, vdev_dir, - cachefile); + if ((slash = strchr(argv[0], '/')) != NULL) + *slash = '\0'; + + error = find_exported_zpool(argv[0], &exported_conf, vdev_dir); if (error == 0) { nvlist_t *nvl = NULL; @@ -2504,12 +2366,23 @@ main(int argc, char **argv) } if (error == 0) - error = spa_import(argv[0], exported_conf, nvl); - if (error == 0) - error = spa_open(argv[0], &spa, FTAG); + error = spa_import_faulted(argv[0], + exported_conf, nvl); nvlist_free(nvl); } + + if (slash != NULL) + *slash = '/'; + } + + if (error == 0) { + if (strchr(argv[0], '/') != NULL) { + error = dmu_objset_open(argv[0], DMU_OST_ANY, + DS_MODE_USER | DS_MODE_READONLY, &os); + } else { + error = spa_open(argv[0], &spa, FTAG); + } } if (error) diff --git a/zfs/zcmd/zdb/zdb_il.c b/zfs/zcmd/zdb/zdb_il.c index 2bfe0e7c9..02d35a050 100644 --- a/zfs/zcmd/zdb/zdb_il.c +++ b/zfs/zcmd/zdb/zdb_il.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zdb_il.c 1.6 07/10/25 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * Print intent log header and statistics. diff --git a/zfs/zcmd/zdump/zdump.c b/zfs/zcmd/zdump/zdump.c index a622d07dd..45be5589d 100644 --- a/zfs/zcmd/zdump/zdump.c +++ b/zfs/zcmd/zdump/zdump.c @@ -3,7 +3,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zdump.c 1.15 06/12/06 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * zdump 7.24 diff --git a/zfs/zcmd/zfs/zfs_iter.c b/zfs/zcmd/zfs/zfs_iter.c index 9e393384c..a22370a02 100644 --- a/zfs/zcmd/zfs/zfs_iter.c +++ b/zfs/zcmd/zfs/zfs_iter.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zfs_iter.c 1.8 07/10/29 SMI" - #include #include #include @@ -56,7 +54,7 @@ typedef struct zfs_node { typedef struct callback_data { uu_avl_t *cb_avl; - int cb_recurse; + int cb_flags; zfs_type_t cb_types; zfs_sort_column_t *cb_sortcol; zprop_list_t **cb_proplist; @@ -65,7 +63,23 @@ typedef struct callback_data { uu_avl_pool_t *avl_pool; /* - * Called for each dataset. If the object the object is of an appropriate type, + * Include snaps if they were requested or if this a zfs list where types + * were not specified and the "listsnapshots" property is set on this pool. + */ +static int +zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb) +{ + zpool_handle_t *zph; + + if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0) + return (cb->cb_types & ZFS_TYPE_SNAPSHOT); + + zph = zfs_get_pool_handle(zhp); + return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL)); +} + +/* + * Called for each dataset. If the object is of an appropriate type, * add it to the avl tree and recurse over any children as necessary. */ static int @@ -73,11 +87,10 @@ zfs_callback(zfs_handle_t *zhp, void *data) { callback_data_t *cb = data; int dontclose = 0; + int include_snaps = zfs_include_snapshots(zhp, cb); - /* - * If this object is of the appropriate type, add it to the AVL tree. - */ - if (zfs_get_type(zhp) & cb->cb_types) { + if ((zfs_get_type(zhp) & cb->cb_types) || + ((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) { uu_avl_index_t idx; zfs_node_t *node = safe_malloc(sizeof (zfs_node_t)); @@ -100,11 +113,10 @@ zfs_callback(zfs_handle_t *zhp, void *data) /* * Recurse if necessary. */ - if (cb->cb_recurse) { + if (cb->cb_flags & ZFS_ITER_RECURSE) { if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) (void) zfs_iter_filesystems(zhp, zfs_callback, data); - if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT && - (cb->cb_types & ZFS_TYPE_SNAPSHOT)) + if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps) (void) zfs_iter_snapshots(zhp, zfs_callback, data); } @@ -296,7 +308,7 @@ zfs_sort(const void *larg, const void *rarg, void *data) if (lstr) ret = strcmp(lstr, rstr); - if (lnum < rnum) + else if (lnum < rnum) ret = -1; else if (lnum > rnum) ret = 1; @@ -312,9 +324,9 @@ zfs_sort(const void *larg, const void *rarg, void *data) } int -zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types, - zfs_sort_column_t *sortcol, zprop_list_t **proplist, zfs_iter_f callback, - void *data, boolean_t args_can_be_paths) +zfs_for_each(int argc, char **argv, int flags, zfs_type_t types, + zfs_sort_column_t *sortcol, zprop_list_t **proplist, + zfs_iter_f callback, void *data) { callback_data_t cb; int ret = 0; @@ -331,7 +343,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types, } cb.cb_sortcol = sortcol; - cb.cb_recurse = recurse; + cb.cb_flags = flags; cb.cb_proplist = proplist; cb.cb_types = types; if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) { @@ -344,7 +356,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types, /* * If given no arguments, iterate over all datasets. */ - cb.cb_recurse = 1; + cb.cb_flags |= ZFS_ITER_RECURSE; ret = zfs_iter_root(g_zfs, zfs_callback, &cb); } else { int i; @@ -357,14 +369,14 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types, * can take volumes as well. */ argtype = types; - if (recurse) { + if (flags & ZFS_ITER_RECURSE) { argtype |= ZFS_TYPE_FILESYSTEM; if (types & ZFS_TYPE_SNAPSHOT) argtype |= ZFS_TYPE_VOLUME; } for (i = 0; i < argc; i++) { - if (args_can_be_paths) { + if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) { zhp = zfs_path_to_zhandle(g_zfs, argv[i], argtype); } else { diff --git a/zfs/zcmd/zfs/zfs_iter.h b/zfs/zcmd/zfs/zfs_iter.h index 55dc5ac91..76a11085a 100644 --- a/zfs/zcmd/zfs/zfs_iter.h +++ b/zfs/zcmd/zfs/zfs_iter.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef ZFS_ITER_H #define ZFS_ITER_H -#pragma ident "@(#)zfs_iter.h 1.6 07/09/17 SMI" - #ifdef __cplusplus extern "C" { #endif @@ -40,8 +38,12 @@ typedef struct zfs_sort_column { boolean_t sc_reverse; } zfs_sort_column_t; -int zfs_for_each(int, char **, boolean_t, zfs_type_t, zfs_sort_column_t *, - zprop_list_t **, zfs_iter_f, void *, boolean_t); +#define ZFS_ITER_RECURSE (1 << 0) +#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1) +#define ZFS_ITER_PROP_LISTSNAPS (1 << 2) + +int zfs_for_each(int, char **, int options, zfs_type_t, + zfs_sort_column_t *, zprop_list_t **, zfs_iter_f, void *); int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t); void zfs_free_sort_columns(zfs_sort_column_t *); diff --git a/zfs/zcmd/zfs/zfs_main.c b/zfs/zcmd/zfs/zfs_main.c index 710e370f9..f9480ceba 100644 --- a/zfs/zcmd/zfs/zfs_main.c +++ b/zfs/zcmd/zfs/zfs_main.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zfs_main.c 1.58 08/03/24 SMI" - #include #include #include @@ -81,9 +79,10 @@ static int zfs_do_allow(int argc, char **argv); static int zfs_do_unallow(int argc, char **argv); /* - * These libumem hooks provide a reasonable set of defaults for the allocator's - * debugging facilities. + * Enable a reasonable set of defaults for libumem debugging on DEBUG builds. */ + +#ifdef DEBUG const char * _umem_debug_init(void) { @@ -95,6 +94,7 @@ _umem_logging_init(void) { return ("fail,contents"); /* $UMEM_LOGGING setting */ } +#endif typedef enum { HELP_CLONE, @@ -173,8 +173,8 @@ get_usage(zfs_help_t idx) { switch (idx) { case HELP_CLONE: - return (gettext("\tclone [-p] " - "\n")); + return (gettext("\tclone [-p] [-o property=value] ... " + " \n")); case HELP_CREATE: return (gettext("\tcreate [-p] [-o property=value] ... " "\n" @@ -190,7 +190,7 @@ get_usage(zfs_help_t idx) "[filesystem|volume|snapshot] ...\n")); case HELP_INHERIT: return (gettext("\tinherit [-r] " - " ...\n")); + " ...\n")); case HELP_UPGRADE: return (gettext("\tupgrade [-v]\n" "\tupgrade [-r] [-V version] <-a | filesystem ...>\n")); @@ -219,11 +219,11 @@ get_usage(zfs_help_t idx) return (gettext("\tsend [-R] [-[iI] snapshot] \n")); case HELP_SET: return (gettext("\tset " - " ...\n")); + " ...\n")); case HELP_SHARE: return (gettext("\tshare <-a | filesystem>\n")); case HELP_SNAPSHOT: - return (gettext("\tsnapshot [-r] " + return (gettext("\tsnapshot [-r] [-o property=value] ... " "\n")); case HELP_UNMOUNT: return (gettext("\tunmount [-f] " @@ -281,14 +281,12 @@ usage_prop_cb(int prop, void *cb) { FILE *fp = cb; - (void) fprintf(fp, "\t%-14s ", zfs_prop_to_name(prop)); + (void) fprintf(fp, "\t%-15s ", zfs_prop_to_name(prop)); - if (prop == ZFS_PROP_CASE) - (void) fprintf(fp, "NO "); - else if (zfs_prop_readonly(prop)) - (void) fprintf(fp, " NO "); + if (zfs_prop_readonly(prop)) + (void) fprintf(fp, " NO "); else - (void) fprintf(fp, " YES "); + (void) fprintf(fp, "YES "); if (zfs_prop_inheritable(prop)) (void) fprintf(fp, " YES "); @@ -363,7 +361,7 @@ usage(boolean_t requested) (void) fprintf(fp, gettext("\nSizes are specified in bytes " "with standard units such as K, M, G, etc.\n")); - (void) fprintf(fp, gettext("\n\nUser-defined properties can " + (void) fprintf(fp, gettext("\nUser-defined properties can " "be specified by using a name containing a colon (:).\n")); } else if (show_permissions) { @@ -397,8 +395,35 @@ usage(boolean_t requested) exit(requested ? 0 : 2); } +static int +parseprop(nvlist_t *props) +{ + char *propname = optarg; + char *propval, *strval; + + if ((propval = strchr(propname, '=')) == NULL) { + (void) fprintf(stderr, gettext("missing " + "'=' for -o option\n")); + return (-1); + } + *propval = '\0'; + propval++; + if (nvlist_lookup_string(props, propname, &strval) == 0) { + (void) fprintf(stderr, gettext("property '%s' " + "specified multiple times\n"), propname); + return (-1); + } + if (nvlist_add_string(props, propname, propval) != 0) { + (void) fprintf(stderr, gettext("internal " + "error: out of memory\n")); + return (-1); + } + return (0); + +} + /* - * zfs clone [-p] + * zfs clone [-p] [-o prop=value] ... * * Given an existing dataset, create a writable copy whose initial contents * are the same as the source. The newly created dataset maintains a @@ -410,21 +435,32 @@ usage(boolean_t requested) static int zfs_do_clone(int argc, char **argv) { - zfs_handle_t *zhp; + zfs_handle_t *zhp = NULL; boolean_t parents = B_FALSE; + nvlist_t *props; int ret; int c; + if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { + (void) fprintf(stderr, gettext("internal error: " + "out of memory\n")); + return (1); + } + /* check options */ - while ((c = getopt(argc, argv, "p")) != -1) { + while ((c = getopt(argc, argv, "o:p")) != -1) { switch (c) { + case 'o': + if (parseprop(props)) + return (1); + break; case 'p': parents = B_TRUE; break; case '?': (void) fprintf(stderr, gettext("invalid option '%c'\n"), optopt); - usage(B_FALSE); + goto usage; } } @@ -435,16 +471,16 @@ zfs_do_clone(int argc, char **argv) if (argc < 1) { (void) fprintf(stderr, gettext("missing source dataset " "argument\n")); - usage(B_FALSE); + goto usage; } if (argc < 2) { (void) fprintf(stderr, gettext("missing target dataset " "argument\n")); - usage(B_FALSE); + goto usage; } if (argc > 2) { (void) fprintf(stderr, gettext("too many arguments\n")); - usage(B_FALSE); + goto usage; } /* open the source dataset */ @@ -466,7 +502,7 @@ zfs_do_clone(int argc, char **argv) } /* pass to libzfs */ - ret = zfs_clone(zhp, argv[1], NULL); + ret = zfs_clone(zhp, argv[1], props); /* create the mountpoint if necessary */ if (ret == 0) { @@ -481,8 +517,16 @@ zfs_do_clone(int argc, char **argv) } zfs_close(zhp); + nvlist_free(props); - return (ret == 0 ? 0 : 1); + return (!!ret); + +usage: + if (zhp) + zfs_close(zhp); + nvlist_free(props); + usage(B_FALSE); + return (-1); } /* @@ -511,11 +555,8 @@ zfs_do_create(int argc, char **argv) boolean_t bflag = B_FALSE; boolean_t parents = B_FALSE; int ret = 1; - nvlist_t *props = NULL; + nvlist_t *props; uint64_t intval; - char *propname; - char *propval = NULL; - char *strval; int canmount; if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { @@ -566,25 +607,8 @@ zfs_do_create(int argc, char **argv) } break; case 'o': - propname = optarg; - if ((propval = strchr(propname, '=')) == NULL) { - (void) fprintf(stderr, gettext("missing " - "'=' for -o option\n")); + if (parseprop(props)) goto error; - } - *propval = '\0'; - propval++; - if (nvlist_lookup_string(props, propname, - &strval) == 0) { - (void) fprintf(stderr, gettext("property '%s' " - "specified multiple times\n"), propname); - goto error; - } - if (nvlist_add_string(props, propname, propval) != 0) { - (void) fprintf(stderr, gettext("internal " - "error: out of memory\n")); - goto error; - } break; case 's': noreserve = B_TRUE; @@ -626,6 +650,7 @@ zfs_do_create(int argc, char **argv) uint64_t spa_version; char *p; zfs_prop_t resv_prop; + char *strval; if (p = strchr(argv[0], '/')) *p = '\0'; @@ -1081,8 +1106,7 @@ static int zfs_do_get(int argc, char **argv) { zprop_get_cbdata_t cb = { 0 }; - boolean_t recurse = B_FALSE; - int i, c; + int i, c, flags = 0; char *value, *fields; int ret; zprop_list_t fake_name = { 0 }; @@ -1104,7 +1128,7 @@ zfs_do_get(int argc, char **argv) cb.cb_literal = B_TRUE; break; case 'r': - recurse = B_TRUE; + flags |= ZFS_ITER_RECURSE; break; case 'H': cb.cb_scripted = B_TRUE; @@ -1232,8 +1256,8 @@ zfs_do_get(int argc, char **argv) cb.cb_first = B_TRUE; /* run for each object */ - ret = zfs_for_each(argc, argv, recurse, ZFS_TYPE_DATASET, NULL, - &cb.cb_proplist, get_callback, &cb, B_FALSE); + ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET, NULL, + &cb.cb_proplist, get_callback, &cb); if (cb.cb_proplist == &fake_name) zprop_free_list(fake_name.pl_next); @@ -1256,29 +1280,44 @@ zfs_do_get(int argc, char **argv) */ static int -inherit_callback(zfs_handle_t *zhp, void *data) +inherit_recurse_cb(zfs_handle_t *zhp, void *data) { char *propname = data; - int ret; + zfs_prop_t prop = zfs_name_to_prop(propname); - ret = zfs_prop_inherit(zhp, propname); - return (ret != 0); + /* + * If we're doing it recursively, then ignore properties that + * are not valid for this type of dataset. + */ + if (prop != ZPROP_INVAL && + !zfs_prop_valid_for_type(prop, zfs_get_type(zhp))) + return (0); + + return (zfs_prop_inherit(zhp, propname) != 0); +} + +static int +inherit_cb(zfs_handle_t *zhp, void *data) +{ + char *propname = data; + + return (zfs_prop_inherit(zhp, propname) != 0); } static int zfs_do_inherit(int argc, char **argv) { - boolean_t recurse = B_FALSE; int c; zfs_prop_t prop; char *propname; int ret; + int flags = 0; /* check options */ while ((c = getopt(argc, argv, "r")) != -1) { switch (c) { case 'r': - recurse = B_TRUE; + flags |= ZFS_ITER_RECURSE; break; case '?': default: @@ -1329,9 +1368,13 @@ zfs_do_inherit(int argc, char **argv) usage(B_FALSE); } - ret = zfs_for_each(argc, argv, recurse, - ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, NULL, NULL, - inherit_callback, propname, B_FALSE); + if (flags & ZFS_ITER_RECURSE) { + ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET, + NULL, NULL, inherit_recurse_cb, propname); + } else { + ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET, + NULL, NULL, inherit_cb, propname); + } return (ret); } @@ -1455,18 +1498,18 @@ upgrade_set_callback(zfs_handle_t *zhp, void *data) static int zfs_do_upgrade(int argc, char **argv) { - boolean_t recurse = B_FALSE; boolean_t all = B_FALSE; boolean_t showversions = B_FALSE; int ret; upgrade_cbdata_t cb = { 0 }; char c; + int flags = ZFS_ITER_ARGS_CAN_BE_PATHS; /* check options */ while ((c = getopt(argc, argv, "rvV:a")) != -1) { switch (c) { case 'r': - recurse = B_TRUE; + flags |= ZFS_ITER_RECURSE; break; case 'v': showversions = B_TRUE; @@ -1493,9 +1536,10 @@ zfs_do_upgrade(int argc, char **argv) argc -= optind; argv += optind; - if ((!all && !argc) && (recurse | cb.cb_version)) + if ((!all && !argc) && ((flags & ZFS_ITER_RECURSE) | cb.cb_version)) usage(B_FALSE); - if (showversions && (recurse || all || cb.cb_version || argc)) + if (showversions && (flags & ZFS_ITER_RECURSE || all || + cb.cb_version || argc)) usage(B_FALSE); if ((all || argc) && (showversions)) usage(B_FALSE); @@ -1523,8 +1567,8 @@ zfs_do_upgrade(int argc, char **argv) /* Upgrade filesystems */ if (cb.cb_version == 0) cb.cb_version = ZPL_VERSION; - ret = zfs_for_each(argc, argv, recurse, ZFS_TYPE_FILESYSTEM, - NULL, NULL, upgrade_set_callback, &cb, B_TRUE); + ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_FILESYSTEM, + NULL, NULL, upgrade_set_callback, &cb); (void) printf(gettext("%llu filesystems upgraded\n"), cb.cb_numupgraded); if (cb.cb_numsamegraded) { @@ -1540,15 +1584,16 @@ zfs_do_upgrade(int argc, char **argv) (void) printf(gettext("This system is currently running " "ZFS filesystem version %llu.\n\n"), ZPL_VERSION); - ret = zfs_for_each(0, NULL, B_TRUE, ZFS_TYPE_FILESYSTEM, - NULL, NULL, upgrade_list_callback, &cb, B_TRUE); + flags |= ZFS_ITER_RECURSE; + ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM, + NULL, NULL, upgrade_list_callback, &cb); found = cb.cb_foundone; cb.cb_foundone = B_FALSE; cb.cb_newer = B_TRUE; - ret = zfs_for_each(0, NULL, B_TRUE, ZFS_TYPE_FILESYSTEM, - NULL, NULL, upgrade_list_callback, &cb, B_TRUE); + ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM, + NULL, NULL, upgrade_list_callback, &cb); if (!cb.cb_foundone && !found) { (void) printf(gettext("All filesystems are " @@ -1706,18 +1751,17 @@ static int zfs_do_list(int argc, char **argv) { int c; - boolean_t recurse = B_FALSE; boolean_t scripted = B_FALSE; static char default_fields[] = "name,used,available,referenced,mountpoint"; - int types = ZFS_TYPE_DATASET; + int types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME; + boolean_t types_specified = B_FALSE; char *fields = NULL; - char *basic_fields = default_fields; list_cbdata_t cb = { 0 }; char *value; int ret; - char *type_subopts[] = { "filesystem", "volume", "snapshot", NULL }; zfs_sort_column_t *sortcol = NULL; + int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS; /* check options */ while ((c = getopt(argc, argv, ":o:rt:Hs:S:")) != -1) { @@ -1726,7 +1770,7 @@ zfs_do_list(int argc, char **argv) fields = optarg; break; case 'r': - recurse = B_TRUE; + flags |= ZFS_ITER_RECURSE; break; case 'H': scripted = B_TRUE; @@ -1749,7 +1793,12 @@ zfs_do_list(int argc, char **argv) break; case 't': types = 0; + types_specified = B_TRUE; + flags &= ~ZFS_ITER_PROP_LISTSNAPS; while (*optarg != '\0') { + static char *type_subopts[] = { "filesystem", + "volume", "snapshot", "all", NULL }; + switch (getsubopt(&optarg, type_subopts, &value)) { case 0: @@ -1761,6 +1810,10 @@ zfs_do_list(int argc, char **argv) case 2: types |= ZFS_TYPE_SNAPSHOT; break; + case 3: + types = ZFS_TYPE_DATASET; + break; + default: (void) fprintf(stderr, gettext("invalid type '%s'\n"), @@ -1785,7 +1838,13 @@ zfs_do_list(int argc, char **argv) argv += optind; if (fields == NULL) - fields = basic_fields; + fields = default_fields; + + /* + * If "-o space" and no types were specified, don't display snapshots. + */ + if (strcmp(fields, "space") == 0 && types_specified == B_FALSE) + types &= ~ZFS_TYPE_SNAPSHOT; /* * If the user specifies '-o all', the zprop_get_list() doesn't @@ -1799,8 +1858,8 @@ zfs_do_list(int argc, char **argv) cb.cb_scripted = scripted; cb.cb_first = B_TRUE; - ret = zfs_for_each(argc, argv, recurse, types, sortcol, &cb.cb_proplist, - list_callback, &cb, B_TRUE); + ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist, + list_callback, &cb); zprop_free_list(cb.cb_proplist); zfs_free_sort_columns(sortcol); @@ -2166,7 +2225,8 @@ zfs_do_set(int argc, char **argv) /* validate property=value argument */ cb.cb_propname = argv[1]; - if ((cb.cb_value = strchr(cb.cb_propname, '=')) == NULL) { + if (((cb.cb_value = strchr(cb.cb_propname, '=')) == NULL) || + (cb.cb_value[1] == '\0')) { (void) fprintf(stderr, gettext("missing value in " "property=value argument\n")); usage(B_FALSE); @@ -2181,15 +2241,14 @@ zfs_do_set(int argc, char **argv) usage(B_FALSE); } - - ret = zfs_for_each(argc - 2, argv + 2, B_FALSE, - ZFS_TYPE_DATASET, NULL, NULL, set_callback, &cb, B_FALSE); + ret = zfs_for_each(argc - 2, argv + 2, NULL, + ZFS_TYPE_DATASET, NULL, NULL, set_callback, &cb); return (ret); } /* - * zfs snapshot [-r] + * zfs snapshot [-r] [-o prop=value] ... * * Creates a snapshot with the given name. While functionally equivalent to * 'zfs create', it is a separate command to differentiate intent. @@ -2200,17 +2259,28 @@ zfs_do_snapshot(int argc, char **argv) boolean_t recursive = B_FALSE; int ret; char c; + nvlist_t *props; + + if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { + (void) fprintf(stderr, gettext("internal error: " + "out of memory\n")); + return (1); + } /* check options */ - while ((c = getopt(argc, argv, ":r")) != -1) { + while ((c = getopt(argc, argv, "ro:")) != -1) { switch (c) { + case 'o': + if (parseprop(props)) + return (1); + break; case 'r': recursive = B_TRUE; break; case '?': (void) fprintf(stderr, gettext("invalid option '%c'\n"), optopt); - usage(B_FALSE); + goto usage; } } @@ -2220,17 +2290,23 @@ zfs_do_snapshot(int argc, char **argv) /* check number of arguments */ if (argc < 1) { (void) fprintf(stderr, gettext("missing snapshot argument\n")); - usage(B_FALSE); + goto usage; } if (argc > 1) { (void) fprintf(stderr, gettext("too many arguments\n")); - usage(B_FALSE); + goto usage; } - ret = zfs_snapshot(g_zfs, argv[0], recursive); + ret = zfs_snapshot(g_zfs, argv[0], recursive, props); + nvlist_free(props); if (ret && recursive) (void) fprintf(stderr, gettext("no snapshots were created\n")); return (ret != 0); + +usage: + nvlist_free(props); + usage(B_FALSE); + return (-1); } /* @@ -2787,14 +2863,17 @@ zfs_do_unallow(int argc, char **argv) char *ds; int error; nvlist_t *zperms = NULL; + int flags = 0; if (parse_allow_args(&argc, &argv, B_TRUE, &ds, &recurse, &zperms) == -1) return (1); - error = zfs_for_each(argc, argv, recurse, + if (recurse) + flags |= ZFS_ITER_RECURSE; + error = zfs_for_each(argc, argv, flags, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_VOLUME, NULL, - NULL, unallow_callback, (void *)zperms, B_FALSE); + NULL, unallow_callback, (void *)zperms); if (zperms) nvlist_free(zperms); @@ -3466,8 +3545,17 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) ZFS_TYPE_FILESYSTEM)) == NULL) return (1); - ret = 1; + if (stat64(entry.mnt_mountp, &statbuf) != 0) { + (void) fprintf(stderr, gettext("cannot %s '%s': %s\n"), + cmdname, path, strerror(errno)); + goto out; + } else if (statbuf.st_ino != path_inode) { + (void) fprintf(stderr, gettext("cannot " + "%s '%s': not a mountpoint\n"), cmdname, path); + goto out; + } + if (op == OP_SHARE) { char nfs_mnt_prop[ZFS_MAXPROPLEN]; char smbshare_prop[ZFS_MAXPROPLEN]; @@ -3495,13 +3583,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mtpt_prop, sizeof (mtpt_prop), NULL, NULL, 0, B_FALSE) == 0); - if (stat64(entry.mnt_mountp, &statbuf) != 0) { - (void) fprintf(stderr, gettext("cannot %s '%s': %s\n"), - cmdname, path, strerror(errno)); - } else if (statbuf.st_ino != path_inode) { - (void) fprintf(stderr, gettext("cannot " - "unmount '%s': not a mountpoint\n"), path); - } else if (is_manual) { + if (is_manual) { ret = zfs_unmount(zhp, NULL, flags); } else if (strcmp(mtpt_prop, "legacy") == 0) { (void) fprintf(stderr, gettext("cannot unmount " @@ -3514,6 +3596,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) } } +out: zfs_close(zhp); return (ret != 0); diff --git a/zfs/zcmd/zfs/zfs_util.h b/zfs/zcmd/zfs/zfs_util.h index ee985ab86..c7f2f1618 100644 --- a/zfs/zcmd/zfs/zfs_util.h +++ b/zfs/zcmd/zfs/zfs_util.h @@ -26,7 +26,7 @@ #ifndef _ZFS_UTIL_H #define _ZFS_UTIL_H -#pragma ident "@(#)zfs_util.h 1.2 06/05/24 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include diff --git a/zfs/zcmd/zinject/translate.c b/zfs/zcmd/zinject/translate.c index 683a3b0aa..c85e024b6 100644 --- a/zfs/zcmd/zinject/translate.c +++ b/zfs/zcmd/zinject/translate.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)translate.c 1.3 07/11/09 SMI" - #include #undef verify /* both libzfs.h and zfs_context.h want to define this */ @@ -47,6 +45,7 @@ #include #include #include +#include #include @@ -164,7 +163,7 @@ object_from_path(const char *dataset, const char *path, struct stat64 *statbuf, sync(); if ((err = dmu_objset_open(dataset, DMU_OST_ZFS, - DS_MODE_STANDARD | DS_MODE_READONLY, &os)) != 0) { + DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) { (void) fprintf(stderr, "cannot open dataset '%s': %s\n", dataset, strerror(err)); return (-1); @@ -249,7 +248,7 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range, * size. */ if ((err = dmu_objset_open(dataset, DMU_OST_ANY, - DS_MODE_STANDARD | DS_MODE_READONLY, &os)) != 0) { + DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) { (void) fprintf(stderr, "cannot open dataset '%s': %s\n", dataset, strerror(err)); goto out; @@ -432,7 +431,8 @@ translate_raw(const char *str, zinject_record_t *record) } int -translate_device(const char *pool, const char *device, zinject_record_t *record) +translate_device(const char *pool, const char *device, err_type_t label_type, + zinject_record_t *record) { char *end; zpool_handle_t *zhp; @@ -448,7 +448,7 @@ translate_device(const char *pool, const char *device, zinject_record_t *record) record->zi_guid = strtoull(device, &end, 16); if (record->zi_guid == 0 || *end != '\0') { - tgt = zpool_find_vdev(zhp, device, &isspare, &iscache); + tgt = zpool_find_vdev(zhp, device, &isspare, &iscache, NULL); if (tgt == NULL) { (void) fprintf(stderr, "cannot find device '%s' in " @@ -460,5 +460,15 @@ translate_device(const char *pool, const char *device, zinject_record_t *record) &record->zi_guid) == 0); } + switch (label_type) { + case TYPE_LABEL_UBERBLOCK: + record->zi_start = offsetof(vdev_label_t, vl_uberblock[0]); + record->zi_end = record->zi_start + VDEV_UBERBLOCK_RING - 1; + break; + case TYPE_LABEL_NVLIST: + record->zi_start = offsetof(vdev_label_t, vl_vdev_phys); + record->zi_end = record->zi_start + VDEV_PHYS_SIZE - 1; + break; + } return (0); } diff --git a/zfs/zcmd/zinject/zinject.c b/zfs/zcmd/zinject/zinject.c index e04939177..02dc18b9c 100644 --- a/zfs/zcmd/zinject/zinject.c +++ b/zfs/zcmd/zinject/zinject.c @@ -19,11 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zinject.c 1.4 07/09/17 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" /* * ZFS Fault Injector @@ -38,15 +38,18 @@ * Errors can be injected into a particular vdev using the '-d' option. This * option takes a path or vdev GUID to uniquely identify the device within a * pool. There are two types of errors that can be injected, EIO and ENXIO, - * that can be controlled through the '-t' option. The default is ENXIO. For + * that can be controlled through the '-e' option. The default is ENXIO. For * EIO failures, any attempt to read data from the device will return EIO, but * subsequent attempt to reopen the device will succeed. For ENXIO failures, * any attempt to read from the device will return EIO, but any attempt to * reopen the device will also return ENXIO. + * For label faults, the -L option must be specified. This allows faults + * to be injected into either the nvlist or uberblock region of all the labels + * for the specified device. * * This form of the command looks like: * - * zinject -d device [-t type] pool + * zinject -d device [-e errno] [-L ] pool * * * DATA FAULTS @@ -165,7 +168,9 @@ static const char *errtable[TYPE_INVAL] = { "config", "bplist", "spacemap", - "errlog" + "errlog", + "uber", + "nvlist" }; static err_type_t @@ -219,9 +224,10 @@ usage(void) "\t\tClear the particular record (if given a numeric ID), or\n" "\t\tall records if 'all' is specificed.\n" "\n" - "\tzinject -d device [-e errno] pool\n" - "\t\tInject a fault into a particular device. 'errno' can either\n" - "\t\tbe 'nxio' (the default) or 'io'.\n" + "\tzinject -d device [-e errno] [-L ] pool\n" + "\t\tInject a fault into a particular device or the device's\n" + "\t\tlabel. Label injection can either be 'nvlist' or 'uber'.\n" + "\t\t'errno' can either be 'nxio' (the default) or 'io'.\n" "\n" "\tzinject -b objset:object:level:blkid pool\n" "\n" @@ -474,6 +480,7 @@ main(int argc, char **argv) int error = 0; int domount = 0; err_type_t type = TYPE_INVAL; + err_type_t label = TYPE_INVAL; zinject_record_t record = { 0 }; char pool[MAXNAMELEN]; char dataset[MAXNAMELEN]; @@ -509,7 +516,7 @@ main(int argc, char **argv) return (0); } - while ((c = getopt(argc, argv, ":ab:d:f:qhc:t:l:mr:e:u")) != -1) { + while ((c = getopt(argc, argv, ":ab:d:f:qhc:t:l:mr:e:uL:")) != -1) { switch (c) { case 'a': flags |= ZINJECT_FLUSH_ARC; @@ -568,7 +575,8 @@ main(int argc, char **argv) range = optarg; break; case 't': - if ((type = name_to_type(optarg)) == TYPE_INVAL) { + if ((type = name_to_type(optarg)) == TYPE_INVAL && + !MOS_TYPE(type)) { (void) fprintf(stderr, "invalid type '%s'\n", optarg); usage(); @@ -578,6 +586,15 @@ main(int argc, char **argv) case 'u': flags |= ZINJECT_UNLOAD_SPA; break; + case 'L': + if ((label = name_to_type(optarg)) == TYPE_INVAL && + !LABEL_TYPE(type)) { + (void) fprintf(stderr, "invalid label type " + "'%s'\n", optarg); + usage(); + return (1); + } + break; case ':': (void) fprintf(stderr, "option -%c requires an " "operand\n", optopt); @@ -654,7 +671,7 @@ main(int argc, char **argv) return (1); } - if (translate_device(pool, device, &record) != 0) + if (translate_device(pool, device, label, &record) != 0) return (1); if (!error) error = ENXIO; diff --git a/zfs/zcmd/zinject/zinject.h b/zfs/zcmd/zinject/zinject.h index 8a912ed0d..adc3efe80 100644 --- a/zfs/zcmd/zinject/zinject.h +++ b/zfs/zcmd/zinject/zinject.h @@ -19,14 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _ZINJECT_H #define _ZINJECT_H -#pragma ident "@(#)zinject.h 1.2 06/05/24 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include @@ -44,17 +44,22 @@ typedef enum { TYPE_BPLIST, /* block pointer list */ TYPE_SPACEMAP, /* space map objects */ TYPE_ERRLOG, /* persistent error log */ + TYPE_LABEL_UBERBLOCK, /* label specific uberblock */ + TYPE_LABEL_NVLIST, /* label specific nvlist */ TYPE_INVAL } err_type_t; #define MOS_TYPE(t) \ - ((t) >= TYPE_MOS && (t) < TYPE_INVAL) + ((t) >= TYPE_MOS && (t) < TYPE_LABEL_UBERBLOCK) + +#define LABEL_TYPE(t) \ + ((t) >= TYPE_LABEL_UBERBLOCK && (t) < TYPE_INVAL) int translate_record(err_type_t type, const char *object, const char *range, int level, zinject_record_t *record, char *poolname, char *dataset); int translate_raw(const char *raw, zinject_record_t *record); int translate_device(const char *pool, const char *device, - zinject_record_t *record); + err_type_t label_type, zinject_record_t *record); void usage(void); extern libzfs_handle_t *g_zfs; diff --git a/zfs/zcmd/zpool/zpool_iter.c b/zfs/zcmd/zpool/zpool_iter.c index 11f5561f2..2f0daefd5 100644 --- a/zfs/zcmd/zpool/zpool_iter.c +++ b/zfs/zcmd/zpool/zpool_iter.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zpool_iter.c 1.5 07/09/17 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/zcmd/zpool/zpool_main.c b/zfs/zcmd/zpool/zpool_main.c index 83c7e72e7..54bba8645 100644 --- a/zfs/zcmd/zpool/zpool_main.c +++ b/zfs/zcmd/zpool/zpool_main.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zpool_main.c 1.54 08/02/13 SMI" - #include #include #include @@ -86,6 +84,8 @@ static int zpool_do_set(int, char **); * These libumem hooks provide a reasonable set of defaults for the allocator's * debugging facilities. */ + +#ifdef DEBUG const char * _umem_debug_init(void) { @@ -97,6 +97,7 @@ _umem_logging_init(void) { return ("fail,contents"); /* $UMEM_LOGGING setting */ } +#endif typedef enum { HELP_ADD, @@ -184,6 +185,7 @@ get_usage(zpool_help_t idx) { return (gettext("\tclear [device]\n")); case HELP_CREATE: return (gettext("\tcreate [-fn] [-o property=value] ... \n" + "\t [-O file-system-property=value] ... \n" "\t [-m mountpoint] [-R root] ...\n")); case HELP_DESTROY: return (gettext("\tdestroy [-f] \n")); @@ -348,11 +350,14 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, * Add a property pair (name, string-value) into a property nvlist. */ static int -add_prop_list(const char *propname, char *propval, nvlist_t **props) +add_prop_list(const char *propname, char *propval, nvlist_t **props, + boolean_t poolprop) { - char *strval; + zpool_prop_t prop = ZPROP_INVAL; + zfs_prop_t fprop; nvlist_t *proplist; - zpool_prop_t prop; + const char *normnm; + char *strval; if (*props == NULL && nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { @@ -363,22 +368,30 @@ add_prop_list(const char *propname, char *propval, nvlist_t **props) proplist = *props; - if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) { - (void) fprintf(stderr, gettext("property '%s' is " - "not a valid pool property\n"), propname); - return (2); + if (poolprop) { + if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) { + (void) fprintf(stderr, gettext("property '%s' is " + "not a valid pool property\n"), propname); + return (2); + } + normnm = zpool_prop_to_name(prop); + } else { + if ((fprop = zfs_name_to_prop(propname)) == ZPROP_INVAL) { + (void) fprintf(stderr, gettext("property '%s' is " + "not a valid file system property\n"), propname); + return (2); + } + normnm = zfs_prop_to_name(fprop); } - /* Use normalized property name for nvlist operations */ - if (nvlist_lookup_string(proplist, zpool_prop_to_name(prop), - &strval) == 0 && prop != ZPOOL_PROP_CACHEFILE) { + if (nvlist_lookup_string(proplist, normnm, &strval) == 0 && + prop != ZPOOL_PROP_CACHEFILE) { (void) fprintf(stderr, gettext("property '%s' " "specified multiple times\n"), propname); return (2); } - if (nvlist_add_string(proplist, zpool_prop_to_name(prop), - propval) != 0) { + if (nvlist_add_string(proplist, normnm, propval) != 0) { (void) fprintf(stderr, gettext("internal " "error: out of memory\n")); return (1); @@ -455,7 +468,8 @@ zpool_do_add(int argc, char **argv) } /* pass off to get_vdev_spec for processing */ - nvroot = make_root_vdev(zhp, force, !force, B_FALSE, argc, argv); + nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun, + argc, argv); if (nvroot == NULL) { zpool_close(zhp); return (1); @@ -534,8 +548,9 @@ zpool_do_remove(int argc, char **argv) } /* - * zpool create [-fn] [-o property=value] ... [-R root] [-m mountpoint] - * ... + * zpool create [-fn] [-o property=value] ... + * [-O file-system-property=value] ... + * [-R root] [-m mountpoint] ... * * -f Force creation, even if devices appear in use * -n Do not create the pool, but display the resulting layout if it @@ -544,6 +559,7 @@ zpool_do_remove(int argc, char **argv) * -m Set default mountpoint for the root dataset. By default it's * '/' * -o Set property=value. + * -O Set fsproperty=value in the pool's root file system * * Creates the named pool according to the given vdev specification. The * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once @@ -561,11 +577,12 @@ zpool_do_create(int argc, char **argv) int ret = 1; char *altroot = NULL; char *mountpoint = NULL; + nvlist_t *fsprops = NULL; nvlist_t *props = NULL; char *propval; /* check options */ - while ((c = getopt(argc, argv, ":fnR:m:o:")) != -1) { + while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) { switch (c) { case 'f': force = B_TRUE; @@ -576,14 +593,14 @@ zpool_do_create(int argc, char **argv) case 'R': altroot = optarg; if (add_prop_list(zpool_prop_to_name( - ZPOOL_PROP_ALTROOT), optarg, &props)) + ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) goto errout; if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), &propval) == 0) break; if (add_prop_list(zpool_prop_to_name( - ZPOOL_PROP_CACHEFILE), "none", &props)) + ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) goto errout; break; case 'm': @@ -598,7 +615,19 @@ zpool_do_create(int argc, char **argv) *propval = '\0'; propval++; - if (add_prop_list(optarg, propval, &props)) + if (add_prop_list(optarg, propval, &props, B_TRUE)) + goto errout; + break; + case 'O': + if ((propval = strchr(optarg, '=')) == NULL) { + (void) fprintf(stderr, gettext("missing " + "'=' for -O option\n")); + goto errout; + } + *propval = '\0'; + propval++; + + if (add_prop_list(optarg, propval, &fsprops, B_FALSE)) goto errout; break; case ':': @@ -640,10 +669,10 @@ zpool_do_create(int argc, char **argv) } /* pass off to get_vdev_spec for bulk processing */ - nvroot = make_root_vdev(NULL, force, !force, B_FALSE, argc - 1, - argv + 1); + nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun, + argc - 1, argv + 1); if (nvroot == NULL) - return (1); + goto errout; /* make_root_vdev() allows 0 toplevel children if there are spares */ if (!zfs_allocatable_devs(nvroot)) { @@ -735,7 +764,8 @@ zpool_do_create(int argc, char **argv) /* * Hand off to libzfs. */ - if (zpool_create(g_zfs, poolname, nvroot, props) == 0) { + if (zpool_create(g_zfs, poolname, + nvroot, props, fsprops) == 0) { zfs_handle_t *pool = zfs_open(g_zfs, poolname, ZFS_TYPE_FILESYSTEM); if (pool != NULL) { @@ -756,9 +786,11 @@ zpool_do_create(int argc, char **argv) errout: nvlist_free(nvroot); + nvlist_free(fsprops); nvlist_free(props); return (ret); badusage: + nvlist_free(fsprops); nvlist_free(props); usage(B_FALSE); return (2); @@ -885,7 +917,7 @@ zpool_do_export(int argc, char **argv) continue; } - if (zpool_export(zhp) != 0) + if (zpool_export(zhp, force) != 0) ret = 1; zpool_close(zhp); @@ -1109,16 +1141,23 @@ show_import(nvlist_t *config) (void) printf(gettext("status: The pool is formatted using an " "incompatible version.\n")); break; + case ZPOOL_STATUS_HOSTID_MISMATCH: (void) printf(gettext("status: The pool was last accessed by " "another system.\n")); break; + case ZPOOL_STATUS_FAULTED_DEV_R: case ZPOOL_STATUS_FAULTED_DEV_NR: (void) printf(gettext("status: One or more devices are " "faulted.\n")); break; + case ZPOOL_STATUS_BAD_LOG: + (void) printf(gettext("status: An intent log record cannot be " + "read.\n")); + break; + default: /* * No other status can be seen when importing pools. @@ -1214,7 +1253,7 @@ show_import(nvlist_t *config) */ static int do_import(nvlist_t *config, const char *newname, const char *mntopts, - int force, nvlist_t *props) + int force, nvlist_t *props, boolean_t allowfaulted) { zpool_handle_t *zhp; char *name; @@ -1267,13 +1306,14 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, } } - if (zpool_import_props(g_zfs, config, newname, props) != 0) + if (zpool_import_props(g_zfs, config, newname, props, + allowfaulted) != 0) return (1); if (newname != NULL) name = (char *)newname; - verify((zhp = zpool_open(g_zfs, name)) != NULL); + verify((zhp = zpool_open_canfail(g_zfs, name)) != NULL); if (zpool_enable_datasets(zhp, mntopts, 0) != 0) { zpool_close(zhp); @@ -1306,6 +1346,11 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, * * -f Force import, even if it appears that the pool is active. * + * -F Import even in the presence of faulted vdevs. This is an + * intentionally undocumented option for testing purposes, and + * treats the pool configuration as complete, leaving any bad + * vdevs in the FAULTED state. + * * -a Import all pools found. * * -o Set property=value and/or temporary mount options (without '='). @@ -1327,17 +1372,18 @@ zpool_do_import(int argc, char **argv) boolean_t do_force = B_FALSE; nvpair_t *elem; nvlist_t *config; - uint64_t searchguid; - char *searchname; + uint64_t searchguid = 0; + char *searchname = NULL; char *propval; nvlist_t *found_config; nvlist_t *props = NULL; boolean_t first; + boolean_t allow_faulted = B_FALSE; uint64_t pool_state; char *cachefile = NULL; /* check options */ - while ((c = getopt(argc, argv, ":afc:d:Do:p:R:")) != -1) { + while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) { switch (c) { case 'a': do_all = B_TRUE; @@ -1364,11 +1410,15 @@ zpool_do_import(int argc, char **argv) case 'f': do_force = B_TRUE; break; + case 'F': + allow_faulted = B_TRUE; + break; case 'o': if ((propval = strchr(optarg, '=')) != NULL) { *propval = '\0'; propval++; - if (add_prop_list(optarg, propval, &props)) + if (add_prop_list(optarg, propval, + &props, B_TRUE)) goto error; } else { mntopts = optarg; @@ -1376,14 +1426,14 @@ zpool_do_import(int argc, char **argv) break; case 'R': if (add_prop_list(zpool_prop_to_name( - ZPOOL_PROP_ALTROOT), optarg, &props)) + ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) goto error; if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), &propval) == 0) break; if (add_prop_list(zpool_prop_to_name( - ZPOOL_PROP_CACHEFILE), "none", &props)) + ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) goto error; break; case ':': @@ -1437,18 +1487,7 @@ zpool_do_import(int argc, char **argv) } } - if (cachefile) - pools = zpool_find_import_cached(g_zfs, cachefile, B_FALSE); - else - pools = zpool_find_import(g_zfs, nsearch, searchdirs, B_FALSE); - - if (pools == NULL) { - free(searchdirs); - return (1); - } - /* - * We now have a list of all available pools in the given directories. * Depending on the arguments given, we do one of the following: * * Iterate through all pools and display information about @@ -1468,11 +1507,38 @@ zpool_do_import(int argc, char **argv) searchguid = strtoull(argv[0], &endptr, 10); if (errno != 0 || *endptr != '\0') searchname = argv[0]; - else - searchname = NULL; found_config = NULL; } + if (cachefile) { + pools = zpool_find_import_cached(g_zfs, cachefile, searchname, + searchguid); + } else if (searchname != NULL) { + pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs, + searchname); + } else { + /* + * It's OK to search by guid even if searchguid is 0. + */ + pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs, + searchguid); + } + + if (pools == NULL) { + if (argc != 0) { + (void) fprintf(stderr, gettext("cannot import '%s': " + "no such pool available\n"), argv[0]); + } + free(searchdirs); + return (1); + } + + /* + * At this point we have a list of import candidate configs. Even if + * we were searching by pool name or guid, we still need to + * post-process the list to deal with pool state and possible + * duplicate names. + */ err = 0; elem = NULL; first = B_TRUE; @@ -1495,7 +1561,7 @@ zpool_do_import(int argc, char **argv) if (do_all) err |= do_import(config, NULL, mntopts, - do_force, props); + do_force, props, allow_faulted); else show_import(config); } else if (searchname != NULL) { @@ -1543,7 +1609,7 @@ zpool_do_import(int argc, char **argv) err = B_TRUE; } else { err |= do_import(found_config, argc == 1 ? NULL : - argv[1], mntopts, do_force, props); + argv[1], mntopts, do_force, props, allow_faulted); } } @@ -2238,7 +2304,8 @@ zpool_do_attach_or_replace(int argc, char **argv, int replacing) return (1); } - nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, argc, argv); + nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE, + argc, argv); if (nvroot == NULL) { zpool_close(zhp); return (1); @@ -2493,7 +2560,7 @@ zpool_do_clear(int argc, char **argv) pool = argv[1]; device = argc == 3 ? argv[2] : NULL; - if ((zhp = zpool_open(g_zfs, pool)) == NULL) + if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) return (1); if (zpool_clear(zhp, device) != 0) @@ -2776,6 +2843,14 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, (void) printf(gettext("too many errors")); break; + case VDEV_AUX_IO_FAILURE: + (void) printf(gettext("experienced I/O failures")); + break; + + case VDEV_AUX_BAD_LOG: + (void) printf(gettext("bad intent log")); + break; + default: (void) printf(gettext("corrupted data")); break; @@ -3058,6 +3133,25 @@ status_callback(zpool_handle_t *zhp, void *data) "to be recovered.\n")); break; + case ZPOOL_STATUS_IO_FAILURE_WAIT: + case ZPOOL_STATUS_IO_FAILURE_CONTINUE: + (void) printf(gettext("status: One or more devices are " + "faulted in response to IO failures.\n")); + (void) printf(gettext("action: Make sure the affected devices " + "are connected, then run 'zpool clear'.\n")); + break; + + case ZPOOL_STATUS_BAD_LOG: + (void) printf(gettext("status: An intent log record " + "could not be read.\n" + "\tWaiting for adminstrator intervention to fix the " + "faulted pool.\n")); + (void) printf(gettext("action: Either restore the affected " + "device(s) and run 'zpool online',\n" + "\tor ignore the intent log records by running " + "'zpool clear'.\n")); + break; + default: /* * The remaining errors can't actually be generated, yet. @@ -3389,6 +3483,11 @@ zpool_do_upgrade(int argc, char **argv) (void) printf(gettext(" 9 refquota and refreservation " "properties\n")); (void) printf(gettext(" 10 Cache devices\n")); + (void) printf(gettext(" 11 Improved scrub performance\n")); + (void) printf(gettext(" 12 Snapshot properties\n")); + (void) printf(gettext(" 13 snapused property\n")); + (void) printf(gettext(" 14 passthrough-x aclinherit " + "support\n")); (void) printf(gettext("For more information on a particular " "version, including supported releases, see:\n\n")); (void) printf("http://www.opensolaris.org/os/community/zfs/" @@ -3473,6 +3572,7 @@ char *hist_event_table[LOG_END] = { "filesystem version upgrade", "refquota set", "refreservation set", + "pool scrub done", }; /* @@ -3527,7 +3627,7 @@ get_history_one(zpool_handle_t *zhp, void *data) ZPOOL_HIST_TXG, &txg) == 0); verify(nvlist_lookup_string(records[i], ZPOOL_HIST_INT_STR, &pathstr) == 0); - if (ievent > LOG_END) + if (ievent >= LOG_END) continue; (void) snprintf(internalstr, sizeof (internalstr), diff --git a/zfs/zcmd/zpool/zpool_util.c b/zfs/zcmd/zpool/zpool_util.c index 2f836709d..f44da4ff6 100644 --- a/zfs/zcmd/zpool/zpool_util.c +++ b/zfs/zcmd/zpool/zpool_util.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "@(#)zpool_util.c 1.5 07/06/21 SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include #include diff --git a/zfs/zcmd/zpool/zpool_util.h b/zfs/zcmd/zpool/zpool_util.h index 686420dfc..e82f3202a 100644 --- a/zfs/zcmd/zpool/zpool_util.h +++ b/zfs/zcmd/zpool/zpool_util.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef ZPOOL_UTIL_H #define ZPOOL_UTIL_H -#pragma ident "@(#)zpool_util.h 1.11 07/09/17 SMI" - #include #include @@ -48,7 +46,7 @@ uint_t num_logs(nvlist_t *nv); */ nvlist_t *make_root_vdev(zpool_handle_t *zhp, int force, int check_rep, - boolean_t isreplace, int argc, char **argv); + boolean_t isreplace, boolean_t dryrun, int argc, char **argv); /* * Pool list functions diff --git a/zfs/zcmd/zpool/zpool_vdev.c b/zfs/zcmd/zpool/zpool_vdev.c index 824100624..10007c149 100644 --- a/zfs/zcmd/zpool/zpool_vdev.c +++ b/zfs/zcmd/zpool/zpool_vdev.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)zpool_vdev.c 1.15 07/11/09 SMI" - /* * Functions to convert between a list of vdevs and an nvlist representing the * configuration. Each entry in the list can be one of: @@ -1352,7 +1350,7 @@ construct_spec(int argc, char **argv) */ nvlist_t * make_root_vdev(zpool_handle_t *zhp, int force, int check_rep, - boolean_t isreplacing, int argc, char **argv) + boolean_t isreplacing, boolean_t dryrun, int argc, char **argv) { nvlist_t *newroot; nvlist_t *poolconfig = NULL; @@ -1394,7 +1392,7 @@ make_root_vdev(zpool_handle_t *zhp, int force, int check_rep, /* * Run through the vdev specification and label any whole disks found. */ - if (make_disks(zhp, newroot) != 0) { + if (!dryrun && make_disks(zhp, newroot) != 0) { nvlist_free(newroot); return (NULL); } diff --git a/zfs/zcmd/ztest/ztest.c b/zfs/zcmd/ztest/ztest.c index a5049b60f..53cc6c709 100644 --- a/zfs/zcmd/ztest/ztest.c +++ b/zfs/zcmd/ztest/ztest.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)ztest.c 1.34 08/04/27 SMI" - /* * The objective of this program is to provide a DMU/ZAP/SPA stress test * that runs entirely in userland, is easy to use, and easy to extend. @@ -79,7 +77,6 @@ #include #include #include -#include #include #include #include @@ -92,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -125,7 +123,6 @@ static int zopt_init = 1; static char *zopt_dir = "/tmp"; static uint64_t zopt_time = 300; /* 5 minutes */ static int zopt_maxfaults; -static uint16_t zopt_write_fail_shift = 5; typedef struct ztest_block_tag { uint64_t bt_objset; @@ -150,7 +147,6 @@ typedef struct ztest_args { hrtime_t za_start; hrtime_t za_stop; hrtime_t za_kill; - traverse_handle_t *za_th; /* * Thread-local variables can go here to aid debugging. */ @@ -176,11 +172,12 @@ ztest_func_t ztest_dmu_objset_create_destroy; ztest_func_t ztest_dmu_snapshot_create_destroy; ztest_func_t ztest_spa_create_destroy; ztest_func_t ztest_fault_inject; +ztest_func_t ztest_spa_rename; ztest_func_t ztest_vdev_attach_detach; ztest_func_t ztest_vdev_LUN_growth; ztest_func_t ztest_vdev_add_remove; +ztest_func_t ztest_vdev_aux_add_remove; ztest_func_t ztest_scrub; -ztest_func_t ztest_spa_rename; typedef struct ztest_info { ztest_func_t *zi_func; /* test function */ @@ -203,16 +200,16 @@ ztest_info_t ztest_info[] = { { ztest_dmu_object_alloc_free, 1, &zopt_always }, { ztest_zap, 30, &zopt_always }, { ztest_zap_parallel, 100, &zopt_always }, - { ztest_traverse, 1, &zopt_often }, { ztest_dsl_prop_get_set, 1, &zopt_sometimes }, - { ztest_dmu_objset_create_destroy, 1, &zopt_sometimes }, - { ztest_dmu_snapshot_create_destroy, 1, &zopt_rarely }, - { ztest_spa_create_destroy, 1, &zopt_sometimes }, + { ztest_dmu_objset_create_destroy, 1, &zopt_sometimes }, + { ztest_dmu_snapshot_create_destroy, 1, &zopt_sometimes }, + { ztest_spa_create_destroy, 1, &zopt_sometimes }, { ztest_fault_inject, 1, &zopt_sometimes }, { ztest_spa_rename, 1, &zopt_rarely }, { ztest_vdev_attach_detach, 1, &zopt_rarely }, { ztest_vdev_LUN_growth, 1, &zopt_rarely }, { ztest_vdev_add_remove, 1, &zopt_vdevtime }, + { ztest_vdev_aux_add_remove, 1, &zopt_vdevtime }, { ztest_scrub, 1, &zopt_vdevtime }, }; @@ -227,6 +224,7 @@ typedef struct ztest_shared { mutex_t zs_vdev_lock; rwlock_t zs_name_lock; uint64_t zs_vdev_primaries; + uint64_t zs_vdev_aux; uint64_t zs_enospc_count; hrtime_t zs_start_time; hrtime_t zs_stop_time; @@ -238,16 +236,15 @@ typedef struct ztest_shared { } ztest_shared_t; static char ztest_dev_template[] = "%s/%s.%llua"; +static char ztest_aux_template[] = "%s/%s.%s.%llu"; static ztest_shared_t *ztest_shared; static int ztest_random_fd; static int ztest_dump_core = 1; -static boolean_t ztest_exiting = B_FALSE; +static boolean_t ztest_exiting; extern uint64_t metaslab_gang_bang; -extern uint16_t zio_zil_fail_shift; -extern uint16_t zio_io_fail_shift; #define ZTEST_DIROBJ 1 #define ZTEST_MICROZAP_OBJ 2 @@ -387,8 +384,6 @@ usage(boolean_t requested) "\t[-E(xisting)] (use existing pool instead of creating new one)\n" "\t[-T time] total run time (default: %llu sec)\n" "\t[-P passtime] time per pass (default: %llu sec)\n" - "\t[-z zil failure rate (default: fail every 2^%llu allocs)]\n" - "\t[-w write failure rate (default: fail every 2^%llu allocs)]\n" "\t[-h] (print help)\n" "", cmdname, @@ -406,9 +401,7 @@ usage(boolean_t requested) zopt_pool, /* -p */ zopt_dir, /* -f */ (u_longlong_t)zopt_time, /* -T */ - (u_longlong_t)zopt_passtime, /* -P */ - (u_longlong_t)zio_zil_fail_shift, /* -z */ - (u_longlong_t)zopt_write_fail_shift); /* -w */ + (u_longlong_t)zopt_passtime); /* -P */ exit(requested ? 0 : 1); } @@ -442,11 +435,8 @@ process_options(int argc, char **argv) /* By default, test gang blocks for blocks 32K and greater */ metaslab_gang_bang = 32 << 10; - /* Default value, fail every 32nd allocation */ - zio_zil_fail_shift = 5; - while ((opt = getopt(argc, argv, - "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:z:w:h")) != EOF) { + "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:h")) != EOF) { value = 0; switch (opt) { case 'v': @@ -462,8 +452,6 @@ process_options(int argc, char **argv) case 'k': case 'T': case 'P': - case 'z': - case 'w': value = nicenumtoull(optarg); } switch (opt) { @@ -518,12 +506,6 @@ process_options(int argc, char **argv) case 'P': zopt_passtime = MAX(1, value); break; - case 'z': - zio_zil_fail_shift = MIN(value, 16); - break; - case 'w': - zopt_write_fail_shift = MIN(value, 16); - break; case 'h': usage(B_TRUE); break; @@ -549,51 +531,58 @@ ztest_get_ashift(void) } static nvlist_t * -make_vdev_file(size_t size) +make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift) { - char dev_name[MAXPATHLEN]; + char pathbuf[MAXPATHLEN]; uint64_t vdev; - uint64_t ashift = ztest_get_ashift(); - int fd; nvlist_t *file; - if (size == 0) { - (void) snprintf(dev_name, sizeof (dev_name), "%s", - "/dev/bogus"); - } else { - vdev = ztest_shared->zs_vdev_primaries++; - (void) sprintf(dev_name, ztest_dev_template, - zopt_dir, zopt_pool, vdev); + if (ashift == 0) + ashift = ztest_get_ashift(); - fd = open(dev_name, O_RDWR | O_CREAT | O_TRUNC, 0666); + if (path == NULL) { + path = pathbuf; + + if (aux != NULL) { + vdev = ztest_shared->zs_vdev_aux; + (void) sprintf(path, ztest_aux_template, + zopt_dir, zopt_pool, aux, vdev); + } else { + vdev = ztest_shared->zs_vdev_primaries++; + (void) sprintf(path, ztest_dev_template, + zopt_dir, zopt_pool, vdev); + } + } + + if (size != 0) { + int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd == -1) - fatal(1, "can't open %s", dev_name); + fatal(1, "can't open %s", path); if (ftruncate(fd, size) != 0) - fatal(1, "can't ftruncate %s", dev_name); + fatal(1, "can't ftruncate %s", path); (void) close(fd); } VERIFY(nvlist_alloc(&file, NV_UNIQUE_NAME, 0) == 0); VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_TYPE, VDEV_TYPE_FILE) == 0); - VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_PATH, dev_name) == 0); + VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_PATH, path) == 0); VERIFY(nvlist_add_uint64(file, ZPOOL_CONFIG_ASHIFT, ashift) == 0); return (file); } static nvlist_t * -make_vdev_raidz(size_t size, int r) +make_vdev_raidz(char *path, char *aux, size_t size, uint64_t ashift, int r) { nvlist_t *raidz, **child; int c; if (r < 2) - return (make_vdev_file(size)); - + return (make_vdev_file(path, aux, size, ashift)); child = umem_alloc(r * sizeof (nvlist_t *), UMEM_NOFAIL); for (c = 0; c < r; c++) - child[c] = make_vdev_file(size); + child[c] = make_vdev_file(path, aux, size, ashift); VERIFY(nvlist_alloc(&raidz, NV_UNIQUE_NAME, 0) == 0); VERIFY(nvlist_add_string(raidz, ZPOOL_CONFIG_TYPE, @@ -612,25 +601,25 @@ make_vdev_raidz(size_t size, int r) } static nvlist_t * -make_vdev_mirror(size_t size, int log, int r, int m) +make_vdev_mirror(char *path, char *aux, size_t size, uint64_t ashift, + int r, int m) { nvlist_t *mirror, **child; int c; if (m < 1) - return (make_vdev_raidz(size, r)); + return (make_vdev_raidz(path, aux, size, ashift, r)); child = umem_alloc(m * sizeof (nvlist_t *), UMEM_NOFAIL); for (c = 0; c < m; c++) - child[c] = make_vdev_raidz(size, r); + child[c] = make_vdev_raidz(path, aux, size, ashift, r); VERIFY(nvlist_alloc(&mirror, NV_UNIQUE_NAME, 0) == 0); VERIFY(nvlist_add_string(mirror, ZPOOL_CONFIG_TYPE, VDEV_TYPE_MIRROR) == 0); VERIFY(nvlist_add_nvlist_array(mirror, ZPOOL_CONFIG_CHILDREN, child, m) == 0); - VERIFY(nvlist_add_uint64(mirror, ZPOOL_CONFIG_IS_LOG, log) == 0); for (c = 0; c < m; c++) nvlist_free(child[c]); @@ -641,7 +630,8 @@ make_vdev_mirror(size_t size, int log, int r, int m) } static nvlist_t * -make_vdev_root(size_t size, int log, int r, int m, int t) +make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift, + int log, int r, int m, int t) { nvlist_t *root, **child; int c; @@ -650,12 +640,15 @@ make_vdev_root(size_t size, int log, int r, int m, int t) child = umem_alloc(t * sizeof (nvlist_t *), UMEM_NOFAIL); - for (c = 0; c < t; c++) - child[c] = make_vdev_mirror(size, log, r, m); + for (c = 0; c < t; c++) { + child[c] = make_vdev_mirror(path, aux, size, ashift, r, m); + VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_IS_LOG, + log) == 0); + } VERIFY(nvlist_alloc(&root, NV_UNIQUE_NAME, 0) == 0); VERIFY(nvlist_add_string(root, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) == 0); - VERIFY(nvlist_add_nvlist_array(root, ZPOOL_CONFIG_CHILDREN, + VERIFY(nvlist_add_nvlist_array(root, aux ? aux : ZPOOL_CONFIG_CHILDREN, child, t) == 0); for (c = 0; c < t; c++) @@ -799,8 +792,8 @@ ztest_spa_create_destroy(ztest_args_t *za) /* * Attempt to create using a bad file. */ - nvroot = make_vdev_root(0, 0, 0, 0, 1); - error = spa_create("ztest_bad_file", nvroot, NULL, NULL); + nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 0, 1); + error = spa_create("ztest_bad_file", nvroot, NULL, NULL, NULL); nvlist_free(nvroot); if (error != ENOENT) fatal(0, "spa_create(bad_file) = %d", error); @@ -808,8 +801,8 @@ ztest_spa_create_destroy(ztest_args_t *za) /* * Attempt to create using a bad mirror. */ - nvroot = make_vdev_root(0, 0, 0, 2, 1); - error = spa_create("ztest_bad_mirror", nvroot, NULL, NULL); + nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 2, 1); + error = spa_create("ztest_bad_mirror", nvroot, NULL, NULL, NULL); nvlist_free(nvroot); if (error != ENOENT) fatal(0, "spa_create(bad_mirror) = %d", error); @@ -819,8 +812,8 @@ ztest_spa_create_destroy(ztest_args_t *za) * what's in the nvroot; we should fail with EEXIST. */ (void) rw_rdlock(&ztest_shared->zs_name_lock); - nvroot = make_vdev_root(0, 0, 0, 0, 1); - error = spa_create(za->za_pool, nvroot, NULL, NULL); + nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 0, 1); + error = spa_create(za->za_pool, nvroot, NULL, NULL, NULL); nvlist_free(nvroot); if (error != EEXIST) fatal(0, "spa_create(whatever) = %d", error); @@ -837,6 +830,22 @@ ztest_spa_create_destroy(ztest_args_t *za) (void) rw_unlock(&ztest_shared->zs_name_lock); } +static vdev_t * +vdev_lookup_by_path(vdev_t *vd, const char *path) +{ + vdev_t *mvd; + + if (vd->vdev_path != NULL && strcmp(path, vd->vdev_path) == 0) + return (vd); + + for (int c = 0; c < vd->vdev_children; c++) + if ((mvd = vdev_lookup_by_path(vd->vdev_child[c], path)) != + NULL) + return (mvd); + + return (NULL); +} + /* * Verify that vdev_add() works as expected. */ @@ -848,22 +857,19 @@ ztest_vdev_add_remove(ztest_args_t *za) nvlist_t *nvroot; int error; - if (zopt_verbose >= 6) - (void) printf("adding vdev\n"); - (void) mutex_lock(&ztest_shared->zs_vdev_lock); - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); ztest_shared->zs_vdev_primaries = spa->spa_root_vdev->vdev_children * leaves; - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_VDEV, FTAG); /* * Make 1/4 of the devices be log devices. */ - nvroot = make_vdev_root(zopt_vdev_size, + nvroot = make_vdev_root(NULL, NULL, zopt_vdev_size, 0, ztest_random(4) == 0, zopt_raidz, zopt_mirrors, 1); error = spa_vdev_add(spa, nvroot); @@ -875,37 +881,86 @@ ztest_vdev_add_remove(ztest_args_t *za) ztest_record_enospc("spa_vdev_add"); else if (error != 0) fatal(0, "spa_vdev_add() = %d", error); - - if (zopt_verbose >= 6) - (void) printf("spa_vdev_add = %d, as expected\n", error); } -static vdev_t * -vdev_lookup_by_path(vdev_t *vd, const char *path) +/* + * Verify that adding/removing aux devices (l2arc, hot spare) works as expected. + */ +void +ztest_vdev_aux_add_remove(ztest_args_t *za) { - int c; - vdev_t *mvd; + spa_t *spa = za->za_spa; + vdev_t *rvd = spa->spa_root_vdev; + spa_aux_vdev_t *sav; + char *aux; + uint64_t guid = 0; + int error; - if (vd->vdev_path != NULL) { - if (vd->vdev_wholedisk == 1) { - /* - * For whole disks, the internal path has 's0', but the - * path passed in by the user doesn't. - */ - if (strlen(path) == strlen(vd->vdev_path) - 2 && - strncmp(path, vd->vdev_path, strlen(path)) == 0) - return (vd); - } else if (strcmp(path, vd->vdev_path) == 0) { - return (vd); + if (ztest_random(2) == 0) { + sav = &spa->spa_spares; + aux = ZPOOL_CONFIG_SPARES; + } else { + sav = &spa->spa_l2cache; + aux = ZPOOL_CONFIG_L2CACHE; + } + + (void) mutex_lock(&ztest_shared->zs_vdev_lock); + + spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); + + if (sav->sav_count != 0 && ztest_random(4) == 0) { + /* + * Pick a random device to remove. + */ + guid = sav->sav_vdevs[ztest_random(sav->sav_count)]->vdev_guid; + } else { + /* + * Find an unused device we can add. + */ + ztest_shared->zs_vdev_aux = 0; + for (;;) { + char path[MAXPATHLEN]; + int c; + (void) sprintf(path, ztest_aux_template, zopt_dir, + zopt_pool, aux, ztest_shared->zs_vdev_aux); + for (c = 0; c < sav->sav_count; c++) + if (strcmp(sav->sav_vdevs[c]->vdev_path, + path) == 0) + break; + if (c == sav->sav_count && + vdev_lookup_by_path(rvd, path) == NULL) + break; + ztest_shared->zs_vdev_aux++; } } - for (c = 0; c < vd->vdev_children; c++) - if ((mvd = vdev_lookup_by_path(vd->vdev_child[c], path)) != - NULL) - return (mvd); + spa_config_exit(spa, SCL_VDEV, FTAG); - return (NULL); + if (guid == 0) { + /* + * Add a new device. + */ + nvlist_t *nvroot = make_vdev_root(NULL, aux, + (zopt_vdev_size * 5) / 4, 0, 0, 0, 0, 1); + error = spa_vdev_add(spa, nvroot); + if (error != 0) + fatal(0, "spa_vdev_add(%p) = %d", nvroot, error); + nvlist_free(nvroot); + } else { + /* + * Remove an existing device. Sometimes, dirty its + * vdev state first to make sure we handle removal + * of devices that have pending state changes. + */ + if (ztest_random(2) == 0) + (void) vdev_online(spa, guid, B_FALSE, NULL); + + error = spa_vdev_remove(spa, guid, B_FALSE); + if (error != 0 && error != EBUSY) + fatal(0, "spa_vdev_remove(%llu) = %d", guid, error); + } + + (void) mutex_unlock(&ztest_shared->zs_vdev_lock); } /* @@ -915,21 +970,25 @@ void ztest_vdev_attach_detach(ztest_args_t *za) { spa_t *spa = za->za_spa; + spa_aux_vdev_t *sav = &spa->spa_spares; vdev_t *rvd = spa->spa_root_vdev; vdev_t *oldvd, *newvd, *pvd; - nvlist_t *root, *file; + nvlist_t *root; uint64_t leaves = MAX(zopt_mirrors, 1) * zopt_raidz; uint64_t leaf, top; uint64_t ashift = ztest_get_ashift(); + uint64_t oldguid; size_t oldsize, newsize; char oldpath[MAXPATHLEN], newpath[MAXPATHLEN]; int replacing; + int oldvd_has_siblings = B_FALSE; + int newvd_is_spare = B_FALSE; + int oldvd_is_log; int error, expected_error; - int fd; (void) mutex_lock(&ztest_shared->zs_vdev_lock); - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); /* * Decide whether to do an attach or a replace. @@ -947,39 +1006,70 @@ ztest_vdev_attach_detach(ztest_args_t *za) leaf = ztest_random(leaves); /* - * Generate the path to this leaf. The filename will end with 'a'. - * We'll alternate replacements with a filename that ends with 'b'. + * Locate this vdev. */ - (void) snprintf(oldpath, sizeof (oldpath), - ztest_dev_template, zopt_dir, zopt_pool, top * leaves + leaf); - - bcopy(oldpath, newpath, MAXPATHLEN); + oldvd = rvd->vdev_child[top]; + if (zopt_mirrors >= 1) + oldvd = oldvd->vdev_child[leaf / zopt_raidz]; + if (zopt_raidz > 1) + oldvd = oldvd->vdev_child[leaf % zopt_raidz]; /* - * If the 'a' file isn't part of the pool, the 'b' file must be. + * If we're already doing an attach or replace, oldvd may be a + * mirror vdev -- in which case, pick a random child. */ - if (vdev_lookup_by_path(rvd, oldpath) == NULL) - oldpath[strlen(oldpath) - 1] = 'b'; - else - newpath[strlen(newpath) - 1] = 'b'; + while (oldvd->vdev_children != 0) { + oldvd_has_siblings = B_TRUE; + ASSERT(oldvd->vdev_children == 2); + oldvd = oldvd->vdev_child[ztest_random(2)]; + } - /* - * Now oldpath represents something that's already in the pool, - * and newpath is the thing we'll try to attach. - */ - oldvd = vdev_lookup_by_path(rvd, oldpath); - newvd = vdev_lookup_by_path(rvd, newpath); - ASSERT(oldvd != NULL); + oldguid = oldvd->vdev_guid; + oldsize = vdev_get_rsize(oldvd); + oldvd_is_log = oldvd->vdev_top->vdev_islog; + (void) strcpy(oldpath, oldvd->vdev_path); pvd = oldvd->vdev_parent; /* - * Make newsize a little bigger or smaller than oldsize. - * If it's smaller, the attach should fail. - * If it's larger, and we're doing a replace, - * we should get dynamic LUN growth when we're done. + * If oldvd has siblings, then half of the time, detach it. */ - oldsize = vdev_get_rsize(oldvd); - newsize = 10 * oldsize / (9 + ztest_random(3)); + if (oldvd_has_siblings && ztest_random(2) == 0) { + spa_config_exit(spa, SCL_VDEV, FTAG); + error = spa_vdev_detach(spa, oldguid, B_FALSE); + if (error != 0 && error != ENODEV && error != EBUSY) + fatal(0, "detach (%s) returned %d", + oldpath, error); + (void) mutex_unlock(&ztest_shared->zs_vdev_lock); + return; + } + + /* + * For the new vdev, choose with equal probability between the two + * standard paths (ending in either 'a' or 'b') or a random hot spare. + */ + if (sav->sav_count != 0 && ztest_random(3) == 0) { + newvd = sav->sav_vdevs[ztest_random(sav->sav_count)]; + newvd_is_spare = B_TRUE; + (void) strcpy(newpath, newvd->vdev_path); + } else { + (void) snprintf(newpath, sizeof (newpath), ztest_dev_template, + zopt_dir, zopt_pool, top * leaves + leaf); + if (ztest_random(2) == 0) + newpath[strlen(newpath) - 1] = 'b'; + newvd = vdev_lookup_by_path(rvd, newpath); + } + + if (newvd) { + newsize = vdev_get_rsize(newvd); + } else { + /* + * Make newsize a little bigger or smaller than oldsize. + * If it's smaller, the attach should fail. + * If it's larger, and we're doing a replace, + * we should get dynamic LUN growth when we're done. + */ + newsize = 10 * oldsize / (9 + ztest_random(3)); + } /* * If pvd is not a mirror or root, the attach should fail with ENOTSUP, @@ -989,12 +1079,17 @@ ztest_vdev_attach_detach(ztest_args_t *za) * * If newvd is too small, it should fail with EOVERFLOW. */ - if (newvd != NULL) - expected_error = EBUSY; - else if (pvd->vdev_ops != &vdev_mirror_ops && - pvd->vdev_ops != &vdev_root_ops && - (!replacing || pvd->vdev_ops == &vdev_replacing_ops)) + if (pvd->vdev_ops != &vdev_mirror_ops && + pvd->vdev_ops != &vdev_root_ops && (!replacing || + pvd->vdev_ops == &vdev_replacing_ops || + pvd->vdev_ops == &vdev_spare_ops)) expected_error = ENOTSUP; + else if (newvd_is_spare && (!replacing || oldvd_is_log)) + expected_error = ENOTSUP; + else if (newvd == oldvd) + expected_error = replacing ? 0 : EBUSY; + else if (vdev_lookup_by_path(rvd, newpath) != NULL) + expected_error = EBUSY; else if (newsize < oldsize) expected_error = EOVERFLOW; else if (ashift > oldvd->vdev_top->vdev_ashift) @@ -1002,36 +1097,16 @@ ztest_vdev_attach_detach(ztest_args_t *za) else expected_error = 0; - /* - * If newvd isn't already part of the pool, create it. - */ - if (newvd == NULL) { - fd = open(newpath, O_RDWR | O_CREAT | O_TRUNC, 0666); - if (fd == -1) - fatal(1, "can't open %s", newpath); - if (ftruncate(fd, newsize) != 0) - fatal(1, "can't ftruncate %s", newpath); - (void) close(fd); - } - - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_VDEV, FTAG); /* * Build the nvlist describing newpath. */ - VERIFY(nvlist_alloc(&file, NV_UNIQUE_NAME, 0) == 0); - VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_TYPE, VDEV_TYPE_FILE) == 0); - VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_PATH, newpath) == 0); - VERIFY(nvlist_add_uint64(file, ZPOOL_CONFIG_ASHIFT, ashift) == 0); + root = make_vdev_root(newpath, NULL, newvd == NULL ? newsize : 0, + ashift, 0, 0, 0, 1); - VERIFY(nvlist_alloc(&root, NV_UNIQUE_NAME, 0) == 0); - VERIFY(nvlist_add_string(root, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) == 0); - VERIFY(nvlist_add_nvlist_array(root, ZPOOL_CONFIG_CHILDREN, - &file, 1) == 0); + error = spa_vdev_attach(spa, oldguid, root, replacing); - error = spa_vdev_attach(spa, oldvd->vdev_guid, root, replacing); - - nvlist_free(file); nvlist_free(root); /* @@ -1046,12 +1121,15 @@ ztest_vdev_attach_detach(ztest_args_t *za) /* * If someone grew the LUN, the replacement may be too small. */ - if (error == EOVERFLOW) + if (error == EOVERFLOW || error == EBUSY) expected_error = error; - if (error != expected_error) { - fatal(0, "attach (%s, %s, %d) returned %d, expected %d", - oldpath, newpath, replacing, error, expected_error); + /* XXX workaround 6690467 */ + if (error != expected_error && expected_error != EBUSY) { + fatal(0, "attach (%s %llu, %s %llu, %d) " + "returned %d, expected %d", + oldpath, (longlong_t)oldsize, newpath, + (longlong_t)newsize, replacing, error, expected_error); } (void) mutex_unlock(&ztest_shared->zs_vdev_lock); @@ -1076,9 +1154,9 @@ ztest_vdev_LUN_growth(ztest_args_t *za) /* * Pick a random leaf vdev. */ - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); vdev = ztest_random(spa->spa_root_vdev->vdev_children * leaves); - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_VDEV, FTAG); (void) sprintf(dev_name, ztest_dev_template, zopt_dir, zopt_pool, vdev); @@ -1135,7 +1213,7 @@ ztest_destroy_cb(char *name, void *arg) * Verify that the dataset contains a directory object. */ error = dmu_objset_open(name, DMU_OST_OTHER, - DS_MODE_STANDARD | DS_MODE_READONLY, &os); + DS_MODE_USER | DS_MODE_READONLY, &os); ASSERT3U(error, ==, 0); error = dmu_object_info(os, ZTEST_DIROBJ, doi); if (error != ENOENT) { @@ -1150,7 +1228,11 @@ ztest_destroy_cb(char *name, void *arg) * Destroy the dataset. */ error = dmu_objset_destroy(name); - ASSERT3U(error, ==, 0); + if (error) { + (void) dmu_objset_open(name, DMU_OST_OTHER, + DS_MODE_USER | DS_MODE_READONLY, &os); + fatal(0, "dmu_objset_destroy(os=%p) = %d\n", &os, error); + } return (0); } @@ -1190,9 +1272,9 @@ void ztest_dmu_objset_create_destroy(ztest_args_t *za) { int error; - objset_t *os; + objset_t *os, *os2; char name[100]; - int mode, basemode, expected_error; + int basemode, expected_error; zilog_t *zilog; uint64_t seq; uint64_t objects; @@ -1202,9 +1284,9 @@ ztest_dmu_objset_create_destroy(ztest_args_t *za) (void) snprintf(name, 100, "%s/%s_temp_%llu", za->za_pool, za->za_pool, (u_longlong_t)za->za_instance); - basemode = DS_MODE_LEVEL(za->za_instance); - if (basemode == DS_MODE_NONE) - basemode++; + basemode = DS_MODE_TYPE(za->za_instance); + if (basemode != DS_MODE_USER && basemode != DS_MODE_OWNER) + basemode = DS_MODE_USER; /* * If this dataset exists from a previous run, process its replay log @@ -1212,9 +1294,9 @@ ztest_dmu_objset_create_destroy(ztest_args_t *za) * (invoked from ztest_destroy_cb() below) should just throw it away. */ if (ztest_random(2) == 0 && - dmu_objset_open(name, DMU_OST_OTHER, DS_MODE_PRIMARY, &os) == 0) { + dmu_objset_open(name, DMU_OST_OTHER, DS_MODE_OWNER, &os) == 0) { zr.zr_os = os; - zil_replay(os, &zr, &zr.zr_assign, ztest_replay_vector); + zil_replay(os, &zr, &zr.zr_assign, ztest_replay_vector, NULL); dmu_objset_close(os); } @@ -1298,21 +1380,24 @@ ztest_dmu_objset_create_destroy(ztest_args_t *za) fatal(0, "created existing dataset, error = %d", error); /* - * Verify that multiple dataset opens are allowed, but only when + * Verify that multiple dataset holds are allowed, but only when * the new access mode is compatible with the base mode. - * We use a mixture of typed and typeless opens, and when the - * open succeeds, verify that the discovered type is correct. */ - for (mode = DS_MODE_STANDARD; mode < DS_MODE_LEVELS; mode++) { - objset_t *os2; - error = dmu_objset_open(name, DMU_OST_OTHER, mode, &os2); - expected_error = (basemode + mode < DS_MODE_LEVELS) ? 0 : EBUSY; - if (error != expected_error) - fatal(0, "dmu_objset_open('%s') = %d, expected %d", - name, error, expected_error); - if (error == 0) + if (basemode == DS_MODE_OWNER) { + error = dmu_objset_open(name, DMU_OST_OTHER, DS_MODE_USER, + &os2); + if (error) + fatal(0, "dmu_objset_open('%s') = %d", name, error); + else dmu_objset_close(os2); } + error = dmu_objset_open(name, DMU_OST_OTHER, DS_MODE_OWNER, &os2); + expected_error = (basemode == DS_MODE_OWNER) ? EBUSY : 0; + if (error != expected_error) + fatal(0, "dmu_objset_open('%s') = %d, expected %d", + name, error, expected_error); + if (error == 0) + dmu_objset_close(os2); zil_close(zilog); dmu_objset_close(os); @@ -1351,152 +1436,6 @@ ztest_dmu_snapshot_create_destroy(ztest_args_t *za) (void) rw_unlock(&ztest_shared->zs_name_lock); } -#define ZTEST_TRAVERSE_BLOCKS 1000 - -static int -ztest_blk_cb(traverse_blk_cache_t *bc, spa_t *spa, void *arg) -{ - ztest_args_t *za = arg; - zbookmark_t *zb = &bc->bc_bookmark; - blkptr_t *bp = &bc->bc_blkptr; - dnode_phys_t *dnp = bc->bc_dnode; - traverse_handle_t *th = za->za_th; - uint64_t size = BP_GET_LSIZE(bp); - - /* - * Level -1 indicates the objset_phys_t or something in its intent log. - */ - if (zb->zb_level == -1) { - if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) { - ASSERT3U(zb->zb_object, ==, 0); - ASSERT3U(zb->zb_blkid, ==, 0); - ASSERT3U(size, ==, sizeof (objset_phys_t)); - za->za_zil_seq = 0; - } else if (BP_GET_TYPE(bp) == DMU_OT_INTENT_LOG) { - ASSERT3U(zb->zb_object, ==, 0); - ASSERT3U(zb->zb_blkid, >, za->za_zil_seq); - za->za_zil_seq = zb->zb_blkid; - } else { - ASSERT3U(zb->zb_object, !=, 0); /* lr_write_t */ - } - - return (0); - } - - ASSERT(dnp != NULL); - - if (bc->bc_errno) - return (ERESTART); - - /* - * Once in a while, abort the traverse. We only do this to odd - * instance numbers to ensure that even ones can run to completion. - */ - if ((za->za_instance & 1) && ztest_random(10000) == 0) - return (EINTR); - - if (bp->blk_birth == 0) { - ASSERT(th->th_advance & ADVANCE_HOLES); - return (0); - } - - if (zb->zb_level == 0 && !(th->th_advance & ADVANCE_DATA) && - bc == &th->th_cache[ZB_DN_CACHE][0]) { - ASSERT(bc->bc_data == NULL); - return (0); - } - - ASSERT(bc->bc_data != NULL); - - /* - * This is an expensive question, so don't ask it too often. - */ - if (((za->za_random ^ th->th_callbacks) & 0xff) == 0) { - void *xbuf = umem_alloc(size, UMEM_NOFAIL); - if (arc_tryread(spa, bp, xbuf) == 0) { - ASSERT(bcmp(bc->bc_data, xbuf, size) == 0); - } - umem_free(xbuf, size); - } - - if (zb->zb_level > 0) { - ASSERT3U(size, ==, 1ULL << dnp->dn_indblkshift); - return (0); - } - - ASSERT(zb->zb_level == 0); - ASSERT3U(size, ==, dnp->dn_datablkszsec << DEV_BSHIFT); - - return (0); -} - -/* - * Verify that live pool traversal works. - */ -void -ztest_traverse(ztest_args_t *za) -{ - spa_t *spa = za->za_spa; - traverse_handle_t *th = za->za_th; - int rc, advance; - uint64_t cbstart, cblimit; - - if (th == NULL) { - advance = 0; - - if (ztest_random(2) == 0) - advance |= ADVANCE_PRE; - - if (ztest_random(2) == 0) - advance |= ADVANCE_PRUNE; - - if (ztest_random(2) == 0) - advance |= ADVANCE_DATA; - - if (ztest_random(2) == 0) - advance |= ADVANCE_HOLES; - - if (ztest_random(2) == 0) - advance |= ADVANCE_ZIL; - - th = za->za_th = traverse_init(spa, ztest_blk_cb, za, advance, - ZIO_FLAG_CANFAIL); - - traverse_add_pool(th, 0, -1ULL); - } - - advance = th->th_advance; - cbstart = th->th_callbacks; - cblimit = cbstart + ((advance & ADVANCE_DATA) ? 100 : 1000); - - while ((rc = traverse_more(th)) == EAGAIN && th->th_callbacks < cblimit) - continue; - - if (zopt_verbose >= 5) - (void) printf("traverse %s%s%s%s %llu blocks to " - "<%llu, %llu, %lld, %llx>%s\n", - (advance & ADVANCE_PRE) ? "pre" : "post", - (advance & ADVANCE_PRUNE) ? "|prune" : "", - (advance & ADVANCE_DATA) ? "|data" : "", - (advance & ADVANCE_HOLES) ? "|holes" : "", - (u_longlong_t)(th->th_callbacks - cbstart), - (u_longlong_t)th->th_lastcb.zb_objset, - (u_longlong_t)th->th_lastcb.zb_object, - (u_longlong_t)th->th_lastcb.zb_level, - (u_longlong_t)th->th_lastcb.zb_blkid, - rc == 0 ? " [done]" : - rc == EINTR ? " [aborted]" : - rc == EAGAIN ? "" : - strerror(rc)); - - if (rc != EAGAIN) { - if (rc != 0 && rc != EINTR) - fatal(0, "traverse_more(%p) = %d", th, rc); - traverse_fini(th); - za->za_th = NULL; - } -} - /* * Verify that dmu_object_{alloc,free} work as expected. */ @@ -1519,7 +1458,7 @@ ztest_dmu_object_alloc_free(ztest_args_t *za) /* * Create a batch object if necessary, and record it in the directory. */ - VERIFY(0 == dmu_read(os, ZTEST_DIROBJ, za->za_diroff, + VERIFY3U(0, ==, dmu_read(os, ZTEST_DIROBJ, za->za_diroff, sizeof (uint64_t), &batchobj)); if (batchobj == 0) { tx = dmu_tx_create(os); @@ -1544,7 +1483,7 @@ ztest_dmu_object_alloc_free(ztest_args_t *za) * Destroy the previous batch of objects. */ for (b = 0; b < batchsize; b++) { - VERIFY(0 == dmu_read(os, batchobj, b * sizeof (uint64_t), + VERIFY3U(0, ==, dmu_read(os, batchobj, b * sizeof (uint64_t), sizeof (uint64_t), &object)); if (object == 0) continue; @@ -1991,7 +1930,7 @@ ztest_dmu_write_parallel(ztest_args_t *za) int b, error; int bs = ZTEST_DIROBJ_BLOCKSIZE; int do_free = 0; - uint64_t off, txg_how; + uint64_t off, txg, txg_how; mutex_t *lp; char osname[MAXNAMELEN]; char iobuf[SPA_MAXBLOCKSIZE]; @@ -2039,6 +1978,7 @@ ztest_dmu_write_parallel(ztest_args_t *za) dmu_tx_abort(tx); return; } + txg = dmu_tx_get_txg(tx); lp = &ztest_shared->zs_sync_lock[b]; (void) mutex_lock(lp); @@ -2046,10 +1986,17 @@ ztest_dmu_write_parallel(ztest_args_t *za) wbt->bt_objset = dmu_objset_id(os); wbt->bt_object = ZTEST_DIROBJ; wbt->bt_offset = off; - wbt->bt_txg = dmu_tx_get_txg(tx); + wbt->bt_txg = txg; wbt->bt_thread = za->za_instance; wbt->bt_seq = ztest_shared->zs_seq[b]++; /* protected by lp */ + /* + * Occasionally, write an all-zero block to test the behavior + * of blocks that compress into holes. + */ + if (off != -1ULL && ztest_random(8) == 0) + bzero(wbt, btsize); + if (off == -1ULL) { dmu_object_info_t *doi = &za->za_doi; char *dboff; @@ -2095,9 +2042,9 @@ ztest_dmu_write_parallel(ztest_args_t *za) dmu_tx_commit(tx); if (ztest_random(10000) == 0) - txg_wait_synced(dmu_objset_pool(os), wbt->bt_txg); + txg_wait_synced(dmu_objset_pool(os), txg); - if (off == -1 || do_free) + if (off == -1ULL || do_free) return; if (ztest_random(2) != 0) @@ -2118,7 +2065,7 @@ ztest_dmu_write_parallel(ztest_args_t *za) return; } blkoff = off - blkoff; - error = dmu_sync(NULL, db, &blk, wbt->bt_txg, NULL, NULL); + error = dmu_sync(NULL, db, &blk, txg, NULL, NULL); dmu_buf_rele(db, FTAG); za->za_dbuf = NULL; @@ -2160,6 +2107,9 @@ ztest_dmu_write_parallel(ztest_args_t *za) if (rbt->bt_objset == 0) /* concurrent free */ return; + if (wbt->bt_objset == 0) /* all-zero overwrite */ + return; + ASSERT3U(rbt->bt_objset, ==, wbt->bt_objset); ASSERT3U(rbt->bt_object, ==, wbt->bt_object); ASSERT3U(rbt->bt_offset, ==, wbt->bt_offset); @@ -2544,21 +2494,6 @@ ztest_dsl_prop_get_set(ztest_args_t *za) (void) rw_unlock(&ztest_shared->zs_name_lock); } -static void -ztest_error_setup(vdev_t *vd, int mode, int mask, uint64_t arg) -{ - int c; - - for (c = 0; c < vd->vdev_children; c++) - ztest_error_setup(vd->vdev_child[c], mode, mask, arg); - - if (vd->vdev_path != NULL) { - vd->vdev_fault_mode = mode; - vd->vdev_fault_mask = mask; - vd->vdev_fault_arg = arg; - } -} - /* * Inject random faults into the on-disk data. */ @@ -2576,60 +2511,90 @@ ztest_fault_inject(ztest_args_t *za) spa_t *spa = za->za_spa; int bshift = SPA_MAXBLOCKSHIFT + 2; /* don't scrog all labels */ int iters = 1000; - vdev_t *vd0; + int maxfaults = zopt_maxfaults; + vdev_t *vd0 = NULL; uint64_t guid0 = 0; - /* - * We can't inject faults when we have no fault tolerance. - */ - if (zopt_maxfaults == 0) - return; - - ASSERT(leaves >= 2); + ASSERT(leaves >= 1); /* - * Pick a random top-level vdev. + * We need SCL_STATE here because we're going to look at vd0->vdev_tsd. */ - spa_config_enter(spa, RW_READER, FTAG); - top = ztest_random(spa->spa_root_vdev->vdev_children); - spa_config_exit(spa, FTAG); + spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); - /* - * Pick a random leaf. - */ - leaf = ztest_random(leaves); + if (ztest_random(2) == 0) { + /* + * Inject errors on a normal data device. + */ + top = ztest_random(spa->spa_root_vdev->vdev_children); + leaf = ztest_random(leaves); - /* - * Generate paths to the first two leaves in this top-level vdev, - * and to the random leaf we selected. We'll induce transient - * I/O errors and random online/offline activity on leaf 0, - * and we'll write random garbage to the randomly chosen leaf. - */ - (void) snprintf(path0, sizeof (path0), - ztest_dev_template, zopt_dir, zopt_pool, top * leaves + 0); - (void) snprintf(pathrand, sizeof (pathrand), - ztest_dev_template, zopt_dir, zopt_pool, top * leaves + leaf); + /* + * Generate paths to the first leaf in this top-level vdev, + * and to the random leaf we selected. We'll induce transient + * write failures and random online/offline activity on leaf 0, + * and we'll write random garbage to the randomly chosen leaf. + */ + (void) snprintf(path0, sizeof (path0), ztest_dev_template, + zopt_dir, zopt_pool, top * leaves + 0); + (void) snprintf(pathrand, sizeof (pathrand), ztest_dev_template, + zopt_dir, zopt_pool, top * leaves + leaf); + + vd0 = vdev_lookup_by_path(spa->spa_root_vdev, path0); + if (vd0 != NULL && maxfaults != 1) { + /* + * Make vd0 explicitly claim to be unreadable, + * or unwriteable, or reach behind its back + * and close the underlying fd. We can do this if + * maxfaults == 0 because we'll fail and reexecute, + * and we can do it if maxfaults >= 2 because we'll + * have enough redundancy. If maxfaults == 1, the + * combination of this with injection of random data + * corruption below exceeds the pool's fault tolerance. + */ + vdev_file_t *vf = vd0->vdev_tsd; + + if (vf != NULL && ztest_random(3) == 0) { + (void) close(vf->vf_vnode->v_fd); + vf->vf_vnode->v_fd = -1; + } else if (ztest_random(2) == 0) { + vd0->vdev_cant_read = B_TRUE; + } else { + vd0->vdev_cant_write = B_TRUE; + } + guid0 = vd0->vdev_guid; + } + } else { + /* + * Inject errors on an l2cache device. + */ + spa_aux_vdev_t *sav = &spa->spa_l2cache; + + if (sav->sav_count == 0) { + spa_config_exit(spa, SCL_STATE, FTAG); + return; + } + vd0 = sav->sav_vdevs[ztest_random(sav->sav_count)]; + guid0 = vd0->vdev_guid; + (void) strcpy(path0, vd0->vdev_path); + (void) strcpy(pathrand, vd0->vdev_path); + + leaf = 0; + leaves = 1; + maxfaults = INT_MAX; /* no limit on cache devices */ + } dprintf("damaging %s and %s\n", path0, pathrand); - spa_config_enter(spa, RW_READER, FTAG); + spa_config_exit(spa, SCL_STATE, FTAG); - /* - * If we can tolerate two or more faults, make vd0 fail randomly. - */ - vd0 = vdev_lookup_by_path(spa->spa_root_vdev, path0); - if (vd0 != NULL && zopt_maxfaults >= 2) { - guid0 = vd0->vdev_guid; - ztest_error_setup(vd0, VDEV_FAULT_COUNT, - (1U << ZIO_TYPE_READ) | (1U << ZIO_TYPE_WRITE), 100); - } - - spa_config_exit(spa, FTAG); + if (maxfaults == 0) + return; /* * If we can tolerate two or more faults, randomly online/offline vd0. */ - if (zopt_maxfaults >= 2 && guid0 != 0) { + if (maxfaults >= 2 && guid0 != 0) { if (ztest_random(10) < 6) (void) vdev_offline(spa, guid0, B_TRUE); else @@ -2674,13 +2639,9 @@ ztest_scrub(ztest_args_t *za) { spa_t *spa = za->za_spa; - mutex_enter(&spa_namespace_lock); - (void) spa_scrub(spa, POOL_SCRUB_EVERYTHING, B_FALSE); - mutex_exit(&spa_namespace_lock); + (void) spa_scrub(spa, POOL_SCRUB_EVERYTHING); (void) poll(NULL, 0, 1000); /* wait a second, then force a restart */ - mutex_enter(&spa_namespace_lock); - (void) spa_scrub(spa, POOL_SCRUB_EVERYTHING, B_FALSE); - mutex_exit(&spa_namespace_lock); + (void) spa_scrub(spa, POOL_SCRUB_EVERYTHING); } /* @@ -2794,10 +2755,9 @@ static void ztest_replace_one_disk(spa_t *spa, uint64_t vdev) { char dev_name[MAXPATHLEN]; - nvlist_t *file, *root; + nvlist_t *root; int error; uint64_t guid; - uint64_t ashift = ztest_get_ashift(); vdev_t *vd; (void) sprintf(dev_name, ztest_dev_template, zopt_dir, zopt_pool, vdev); @@ -2805,22 +2765,14 @@ ztest_replace_one_disk(spa_t *spa, uint64_t vdev) /* * Build the nvlist describing dev_name. */ - VERIFY(nvlist_alloc(&file, NV_UNIQUE_NAME, 0) == 0); - VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_TYPE, VDEV_TYPE_FILE) == 0); - VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_PATH, dev_name) == 0); - VERIFY(nvlist_add_uint64(file, ZPOOL_CONFIG_ASHIFT, ashift) == 0); + root = make_vdev_root(dev_name, NULL, 0, 0, 0, 0, 0, 1); - VERIFY(nvlist_alloc(&root, NV_UNIQUE_NAME, 0) == 0); - VERIFY(nvlist_add_string(root, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) == 0); - VERIFY(nvlist_add_nvlist_array(root, ZPOOL_CONFIG_CHILDREN, - &file, 1) == 0); - - spa_config_enter(spa, RW_READER, FTAG); + spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); if ((vd = vdev_lookup_by_path(spa->spa_root_vdev, dev_name)) == NULL) guid = 0; else guid = vd->vdev_guid; - spa_config_exit(spa, FTAG); + spa_config_exit(spa, SCL_VDEV, FTAG); error = spa_vdev_attach(spa, guid, root, B_TRUE); if (error != 0 && error != EBUSY && @@ -2829,7 +2781,6 @@ ztest_replace_one_disk(spa_t *spa, uint64_t vdev) error != EDOM) fatal(0, "spa_vdev_attach(in-place) = %d", error); - nvlist_free(file); nvlist_free(root); } @@ -2855,12 +2806,12 @@ ztest_verify_blocks(char *pool) isa = strdup(isa); /* LINTED */ (void) sprintf(bin, - "/usr/sbin%.*s/zdb -bc%s%s -U /tmp/zpool.cache -O %s %s", + "/usr/sbin%.*s/zdb -bc%s%s -U /tmp/zpool.cache %s", isalen, isa, zopt_verbose >= 3 ? "s" : "", zopt_verbose >= 4 ? "v" : "", - ztest_random(2) == 0 ? "pre" : "post", pool); + pool); free(isa); if (zopt_verbose >= 5) @@ -2932,7 +2883,7 @@ ztest_spa_import_export(char *oldname, char *newname) /* * Export it. */ - error = spa_export(oldname, &config); + error = spa_export(oldname, &config, B_FALSE); if (error) fatal(0, "spa_export('%s') = %d", oldname, error); @@ -2980,38 +2931,23 @@ ztest_spa_import_export(char *oldname, char *newname) nvlist_free(config); } -/* ARGSUSED */ static void * -ztest_suspend_monitor(void *arg) +ztest_resume(void *arg) { - spa_t *spa; - int error; - - error = spa_open(zopt_pool, &spa, FTAG); - if (error) { - (void) printf("Unable to monitor pool '%s'\n", zopt_pool); - return (NULL); - } + spa_t *spa = arg; while (!ztest_exiting) { - mutex_enter(&spa->spa_zio_lock); - while (!ztest_exiting && list_is_empty(&spa->spa_zio_list)) - cv_wait(&spa->spa_zio_cv, &spa->spa_zio_lock); - mutex_exit(&spa->spa_zio_lock); + (void) poll(NULL, 0, 1000); - (void) sleep(3); - /* - * We don't hold the spa_config_lock since the pool is in - * complete failure mode and there is no way for us to - * change the vdev config when we're in this state. - */ - while ((error = zio_vdev_resume_io(spa)) != 0) { - (void) printf("I/O could not be resumed, %d\n", error); - (void) sleep(1); - } - vdev_clear(spa, NULL, B_TRUE); + if (!spa_suspended(spa)) + continue; + + spa_vdev_state_enter(spa); + vdev_clear(spa, NULL); + (void) spa_vdev_state_exit(spa, NULL, 0); + + zio_resume(spa); } - spa_close(spa, FTAG); return (NULL); } @@ -3090,7 +3026,9 @@ ztest_run(char *pool) ztest_args_t *za; spa_t *spa; char name[100]; - thread_t tid; + thread_t resume_tid; + + ztest_exiting = B_FALSE; (void) _mutex_init(&zs->zs_vdev_lock, USYNC_THREAD, NULL); (void) rwlock_init(&zs->zs_name_lock, USYNC_THREAD, NULL); @@ -3115,9 +3053,7 @@ ztest_run(char *pool) * Kick off a replacement of the disk we just obliterated. */ kernel_init(FREAD | FWRITE); - error = spa_open(pool, &spa, FTAG); - if (error) - fatal(0, "spa_open(%s) = %d", pool, error); + VERIFY(spa_open(pool, &spa, FTAG) == 0); ztest_replace_one_disk(spa, 0); if (zopt_verbose >= 5) show_pool_stats(spa); @@ -3147,24 +3083,16 @@ ztest_run(char *pool) } mutex_exit(&spa_namespace_lock); - /* - * Create a thread to handling complete pool failures. This - * thread will kickstart the I/Os when they suspend. We must - * start the thread before setting the zio_io_fail_shift, which - * will indicate our failure rate. - */ - error = thr_create(0, 0, ztest_suspend_monitor, NULL, THR_BOUND, &tid); - if (error) { - fatal(0, "can't create suspend monitor thread: error %d", - t, error); - } - /* * Open our pool. */ - error = spa_open(pool, &spa, FTAG); - if (error) - fatal(0, "spa_open() = %d", error); + VERIFY(spa_open(pool, &spa, FTAG) == 0); + + /* + * Create a thread to periodically resume suspended I/O. + */ + VERIFY(thr_create(0, 0, ztest_resume, spa, THR_BOUND, + &resume_tid) == 0); /* * Verify that we can safely inquire about about any object, @@ -3191,9 +3119,6 @@ ztest_run(char *pool) if (zopt_verbose >= 4) (void) printf("starting main threads...\n"); - /* Let failures begin */ - zio_io_fail_shift = zopt_write_fail_shift; - za[0].za_start = gethrtime(); za[0].za_stop = za[0].za_start + zopt_passtime * NANOSEC; za[0].za_stop = MIN(za[0].za_stop, zs->zs_stop_time); @@ -3232,7 +3157,7 @@ ztest_run(char *pool) name, error); } error = dmu_objset_open(name, DMU_OST_OTHER, - DS_MODE_STANDARD, &za[d].za_os); + DS_MODE_USER, &za[d].za_os); if (error) fatal(0, "dmu_objset_open('%s') = %d", name, error); @@ -3241,23 +3166,16 @@ ztest_run(char *pool) ztest_dmu_check_future_leak(&za[t]); zr.zr_os = za[d].za_os; zil_replay(zr.zr_os, &zr, &zr.zr_assign, - ztest_replay_vector); + ztest_replay_vector, NULL); za[d].za_zilog = zil_open(za[d].za_os, NULL); } - error = thr_create(0, 0, ztest_thread, &za[t], THR_BOUND, - &za[t].za_thread); - if (error) - fatal(0, "can't create thread %d: error %d", - t, error); + VERIFY(thr_create(0, 0, ztest_thread, &za[t], THR_BOUND, + &za[t].za_thread) == 0); } while (--t >= 0) { - error = thr_join(za[t].za_thread, NULL, NULL); - if (error) - fatal(0, "thr_join(%d) = %d", t, error); - if (za[t].za_th) - traverse_fini(za[t].za_th); + VERIFY(thr_join(za[t].za_thread, NULL, NULL) == 0); if (t < zopt_datasets) { zil_close(za[t].za_zilog); dmu_objset_close(za[t].za_os); @@ -3288,6 +3206,12 @@ ztest_run(char *pool) txg_wait_synced(spa_get_dsl(spa), 0); + umem_free(za, zopt_threads * sizeof (ztest_args_t)); + + /* Kill the resume thread */ + ztest_exiting = B_TRUE; + VERIFY(thr_join(resume_tid, NULL, NULL) == 0); + /* * Right before closing the pool, kick off a bunch of async I/O; * spa_close() should wait for it to complete. @@ -3295,18 +3219,6 @@ ztest_run(char *pool) for (t = 1; t < 50; t++) dmu_prefetch(spa->spa_meta_objset, t, 0, 1 << 15); - /* Shutdown the suspend monitor thread */ - zio_io_fail_shift = 0; - ztest_exiting = B_TRUE; - mutex_enter(&spa->spa_zio_lock); - cv_broadcast(&spa->spa_zio_cv); - mutex_exit(&spa->spa_zio_lock); - error = thr_join(tid, NULL, NULL); - if (error) - fatal(0, "thr_join(%d) = %d", tid, error); - - umem_free(za, zopt_threads * sizeof (ztest_args_t)); - spa_close(spa, FTAG); kernel_fini(); @@ -3355,8 +3267,9 @@ ztest_init(char *pool) */ (void) spa_destroy(pool); ztest_shared->zs_vdev_primaries = 0; - nvroot = make_vdev_root(zopt_vdev_size, 0, zopt_raidz, zopt_mirrors, 1); - error = spa_create(pool, nvroot, NULL, NULL); + nvroot = make_vdev_root(NULL, NULL, zopt_vdev_size, 0, + 0, zopt_raidz, zopt_mirrors, 1); + error = spa_create(pool, nvroot, NULL, NULL, NULL); nvlist_free(nvroot); if (error) @@ -3387,7 +3300,7 @@ main(int argc, char **argv) (void) setvbuf(stdout, NULL, _IOLBF, 0); /* Override location of zpool.cache */ - spa_config_dir = "/tmp"; + spa_config_path = "/tmp/zpool.cache"; ztest_random_fd = open("/dev/urandom", O_RDONLY);