From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZzWl7-0004Rd-9W for mharc-grub-devel@gnu.org; Thu, 19 Nov 2015 16:28:49 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59668) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZzWl1-0004RX-Jl for grub-devel@gnu.org; Thu, 19 Nov 2015 16:28:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZzWkx-000718-Oh for grub-devel@gnu.org; Thu, 19 Nov 2015 16:28:43 -0500 Received: from mail.kernel.org ([198.145.29.136]:35971) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZzWkx-000711-9z for grub-devel@gnu.org; Thu, 19 Nov 2015 16:28:39 -0500 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id ECBB92054D; Thu, 19 Nov 2015 21:28:34 +0000 (UTC) Received: from localhost (unknown [116.126.178.217]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id B573B205F4; Thu, 19 Nov 2015 21:28:28 +0000 (UTC) Date: Fri, 20 Nov 2015 05:28:24 +0800 From: Jaegeuk Kim To: grub-devel@gnu.org, linux-f2fs-devel@lists.sourceforge.net Subject: Re: [PATCH v3] F2FS support Message-ID: <20151119212824.GA11666@jaegeuk.local> References: <1427185140-41120-1-git-send-email-jaegeuk@kernel.org> <20150403224908.GB25673@jaegeuk-mac02.mot.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20150403224908.GB25673@jaegeuk-mac02.mot.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Virus-Scanned: ClamAV using ClamSMTP Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 198.145.29.136 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Nov 2015 21:28:48 -0000 Hello, Change log from v2: o Enhance the code quality suggested by Andrei Sorry for the long delay. Could you please check this patch? Thank you so much, --- >& --- >From 2c0e1d33533fc9fb2686f0e2c17efca11ce57e2f Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 17 Nov 2015 12:45:13 -0800 Subject: [PATCH] F2FS support "F2FS (Flash-Friendly File System) is flash-friendly file system which wa= s merged into Linux kernel v3.8 in 2013. The motive for F2FS was to build a file system that from the start, takes= into account the characteristics of NAND flash memory-based storage devices (s= uch as solid-state disks, eMMC, and SD cards). F2FS was designed on a basis of a log-structured file system approach, wh= ich remedies some known issues of the older log structured file systems, such= as the snowball effect of wandering trees and high cleaning overhead. In add= ition, since a NAND-based storage device shows different characteristics accordi= ng to its internal geometry or flash memory management scheme (such as the Flas= h Translation Layer or FTL), it supports various parameters not only for configuring on-disk layout, but also for selecting allocation and cleanin= g algorithm.", quote by https://en.wikipedia.org/wiki/F2FS. The source codes for F2FS are available from: http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs-tools.git Signed-off-by: Jaegeuk Kim --- Makefile.util.def | 7 + docs/grub.texi | 5 +- grub-core/Makefile.core.def | 5 + grub-core/fs/f2fs.c | 1291 ++++++++++++++++++++++++++++++++++++= ++++++ po/exclude.pot | 1 + tests/f2fs_test.in | 19 + tests/util/grub-fs-tester.in | 11 +- 7 files changed, 1335 insertions(+), 4 deletions(-) create mode 100644 grub-core/fs/f2fs.c create mode 100644 tests/f2fs_test.in diff --git a/Makefile.util.def b/Makefile.util.def index db7e8ec..84627bb 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -99,6 +99,7 @@ library =3D { common =3D grub-core/fs/ext2.c; common =3D grub-core/fs/fat.c; common =3D grub-core/fs/exfat.c; + common =3D grub-core/fs/f2fs.c; common =3D grub-core/fs/fshelp.c; common =3D grub-core/fs/hfs.c; common =3D grub-core/fs/hfsplus.c; @@ -766,6 +767,12 @@ script =3D { =20 script =3D { testcase; + name =3D f2fs_test; + common =3D tests/f2fs_test.in; +}; + +script =3D { + testcase; name =3D nilfs2_test; common =3D tests/nilfs2_test.in; }; diff --git a/docs/grub.texi b/docs/grub.texi index 1df3db2..e5a80f3 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -360,7 +360,8 @@ blocklist notation. The currently supported filesyste= m types are @dfn{Amiga Fast FileSystem (AFFS)}, @dfn{AtheOS fs}, @dfn{BeFS}, @dfn{BtrFS} (including raid0, raid1, raid10, gzip and lzo), @dfn{cpio} (little- and big-endian bin, odc and newc variants), -@dfn{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{exFAT}, @d= fn{HFS}, +@dfn{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{exFAT}, +@dfn{f2fs}, @dfn{HFS}, @dfn{HFS+}, @dfn{ISO9660} (including Joliet, Rock-ridge and multi-chunk = files), @dfn{JFS}, @dfn{Minix fs} (versions 1, 2 and 3), @dfn{nilfs2}, @dfn{NTFS} (including compression), @dfn{ReiserFS}, @dfn{ROMFS}, @@ -5347,7 +5348,7 @@ NTFS, JFS, UDF, HFS+, exFAT, long filenames in FAT,= Joliet part of ISO9660 are treated as UTF-16 as per specification. AFS and BFS are read as UTF-8, again according to specification. BtrFS, cpio, tar, squash4, m= inix, minix2, minix3, ROMFS, ReiserFS, XFS, ext2, ext3, ext4, FAT (short names= ), -RockRidge part of ISO9660, nilfs2, UFS1, UFS2 and ZFS are assumed +f2fs, RockRidge part of ISO9660, nilfs2, UFS1, UFS2 and ZFS are assumed to be UTF-8. This might be false on systems configured with legacy chars= et but as long as the charset used is superset of ASCII you should be able = to access ASCII-named files. And it's recommended to configure your system = to use diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index d9fa0e3..b585ade 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1278,6 +1278,11 @@ module =3D { }; =20 module =3D { + name =3D f2fs; + common =3D fs/f2fs.c; +}; + +module =3D { name =3D fshelp; common =3D fs/fshelp.c; }; diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c new file mode 100644 index 0000000..df0add8 --- /dev/null +++ b/grub-core/fs/f2fs.c @@ -0,0 +1,1291 @@ +/* + * f2fs.c - Flash-Friendly File System + * + * Written by Jaegeuk Kim + * + * Copyright (C) 2015 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* F2FS Magic Number */ +#define F2FS_SUPER_MAGIC 0xF2F52010 +#define CHECKSUM_OFFSET 4092 + +/* byte-size offset */ +#define F2FS_SUPER_OFFSET ((grub_disk_addr_t)1024) +#define F2FS_SUPER_OFFSET0 (F2FS_SUPER_OFFSET >> GRUB_DISK_SECTOR_BITS) +#define F2FS_SUPER_OFFSET1 ((F2FS_SUPER_OFFSET + F2FS_BLKSIZE) >> \ + GRUB_DISK_SECTOR_BITS) + +/* 12 bits for 4096 bytes */ +#define F2FS_MAX_LOG_SECTOR_SIZE 12 + +/* 9 bits for 512 bytes */ +#define F2FS_MIN_LOG_SECTOR_SIZE 9 + +/* support only 4KB block */ +#define F2FS_BLK_BITS 12 +#define F2FS_BLKSIZE (1 << F2FS_BLK_BITS) +#define F2FS_BLK_SEC_BITS (F2FS_BLK_BITS - GRUB_DISK_SECTOR_BITS) + +#define VERSION_LEN 256 +#define F2FS_MAX_EXTENSION 64 + +#define CP_COMPACT_SUM_FLAG 0x00000004 +#define CP_UMOUNT_FLAG 0x00000001 + +#define MAX_ACTIVE_LOGS 16 +#define MAX_ACTIVE_NODE_LOGS 8 +#define MAX_ACTIVE_DATA_LOGS 8 +#define NR_CURSEG_DATA_TYPE 3 +#define NR_CURSEG_NODE_TYPE 3 +#define NR_CURSEG_TYPE (NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE) + +#define ENTRIES_IN_SUM 512 +#define SUMMARY_SIZE 7 +#define SUM_FOOTER_SIZE 5 +#define JENTRY_SIZE (sizeof(struct grub_f2fs_nat_jent)) +#define SUM_ENTRIES_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM) +#define SUM_JOURNAL_SIZE (F2FS_BLKSIZE - SUM_FOOTER_SIZE -\ + SUM_ENTRIES_SIZE) +#define NAT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) / JENTRY_SIZE) +#define NAT_JOURNAL_RESERVED ((SUM_JOURNAL_SIZE - 2) % JENTRY_SIZE) + +#define NAT_ENTRY_SIZE (sizeof(struct grub_f2fs_nat_entry)) +#define NAT_ENTRY_PER_BLOCK (F2FS_BLKSIZE / NAT_ENTRY_SIZE) + +#define F2FS_NAME_LEN 255 +#define F2FS_SLOT_LEN 8 +#define NR_DENTRY_IN_BLOCK 214 +#define SIZE_OF_DIR_ENTRY 11 /* by byte */ +#define BITS_PER_BYTE 8 +#define SIZE_OF_DENTRY_BITMAP ((NR_DENTRY_IN_BLOCK + BITS_PER_BYTE - 1) = / \ + BITS_PER_BYTE) +#define SIZE_OF_RESERVED (F2FS_BLKSIZE - ((SIZE_OF_DIR_ENTRY + \ + F2FS_SLOT_LEN) * \ + NR_DENTRY_IN_BLOCK + SIZE_OF_DENTRY_BITMAP)) + +#define F2FS_INLINE_XATTR_ADDRS 50 /* 200 bytes for inline xattrs */ +#define DEF_ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ + +#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ +#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ +#define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1) +#define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2) +#define NODE_IND1_BLOCK (DEF_ADDRS_PER_INODE + 3) +#define NODE_IND2_BLOCK (DEF_ADDRS_PER_INODE + 4) +#define NODE_DIND_BLOCK (DEF_ADDRS_PER_INODE + 5) + +#define MAX_INLINE_DATA (4 * (DEF_ADDRS_PER_INODE - \ + F2FS_INLINE_XATTR_ADDRS - 1)) +#define NR_INLINE_DENTRY (MAX_INLINE_DATA * BITS_PER_BYTE / \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + BITS_PER_BYTE + 1)) +#define INLINE_DENTRY_BITMAP_SIZE ((NR_INLINE_DENTRY + \ + BITS_PER_BYTE - 1) / BITS_PER_BYTE) +#define INLINE_RESERVED_SIZE (MAX_INLINE_DATA - \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + NR_INLINE_DENTRY + INLINE_DENTRY_BITMAP_SIZE)) +#define CURSEG_HOT_DATA 0 + +#define CKPT_FLAG_SET(ckpt, f) \ + (ckpt)->ckpt_flags & grub_cpu_to_le32_compile_time (f) + +#define F2FS_INLINE_XATTR 0x01 /* file inline xattr flag */ +#define F2FS_INLINE_DATA 0x02 /* file inline data flag */ +#define F2FS_INLINE_DENTRY 0x04 /* file inline dentry flag */ +#define F2FS_DATA_EXIST 0x08 /* file inline data exist flag */ +#define F2FS_INLINE_DOTS 0x10 /* file having implicit dot dentries */ + +enum FILE_TYPE +{ + F2FS_FT_UNKNOWN, + F2FS_FT_REG_FILE =3D 1, + F2FS_FT_DIR =3D 2, + F2FS_FT_SYMLINK =3D 7, +}; + +struct grub_f2fs_superblock +{ + grub_uint32_t magic; + grub_uint16_t dummy1[2]; + grub_uint32_t log_sectorsize; + grub_uint32_t log_sectors_per_block; + grub_uint32_t log_blocksize; + grub_uint32_t log_blocks_per_seg; + grub_uint32_t segs_per_sec; + grub_uint32_t secs_per_zone; + grub_uint32_t checksum_offset; + grub_uint8_t dummy2[40]; + grub_uint32_t cp_blkaddr; + grub_uint32_t sit_blkaddr; + grub_uint32_t nat_blkaddr; + grub_uint32_t ssa_blkaddr; + grub_uint32_t main_blkaddr; + grub_uint32_t root_ino; + grub_uint32_t node_ino; + grub_uint32_t meta_ino; + grub_uint8_t uuid[16]; + grub_uint16_t volume_name[512]; + grub_uint32_t extension_count; + grub_uint8_t extension_list[F2FS_MAX_EXTENSION][8]; + grub_uint32_t cp_payload; + grub_uint8_t version[VERSION_LEN]; + grub_uint8_t init_version[VERSION_LEN]; +} GRUB_PACKED; + +struct grub_f2fs_checkpoint +{ + grub_uint64_t checkpoint_ver; + grub_uint64_t user_block_count; + grub_uint64_t valid_block_count; + grub_uint32_t rsvd_segment_count; + grub_uint32_t overprov_segment_count; + grub_uint32_t free_segment_count; + grub_uint32_t cur_node_segno[MAX_ACTIVE_NODE_LOGS]; + grub_uint16_t cur_node_blkoff[MAX_ACTIVE_NODE_LOGS]; + grub_uint32_t cur_data_segno[MAX_ACTIVE_DATA_LOGS]; + grub_uint16_t cur_data_blkoff[MAX_ACTIVE_DATA_LOGS]; + grub_uint32_t ckpt_flags; + grub_uint32_t cp_pack_total_block_count; + grub_uint32_t cp_pack_start_sum; + grub_uint32_t valid_node_count; + grub_uint32_t valid_inode_count; + grub_uint32_t next_free_nid; + grub_uint32_t sit_ver_bitmap_bytesize; + grub_uint32_t nat_ver_bitmap_bytesize; + grub_uint32_t checksum_offset; + grub_uint64_t elapsed_time; + grub_uint8_t alloc_type[MAX_ACTIVE_LOGS]; + grub_uint8_t sit_nat_version_bitmap[3900]; + grub_uint32_t checksum; +} GRUB_PACKED; + +struct grub_f2fs_nat_entry { + grub_uint8_t version; + grub_uint32_t ino; + grub_uint32_t block_addr; +} GRUB_PACKED; + +struct grub_f2fs_nat_jent +{ + grub_uint32_t nid; + struct grub_f2fs_nat_entry ne; +} GRUB_PACKED; + +struct grub_f2fs_nat_journal { + grub_uint16_t n_nats; + struct grub_f2fs_nat_jent entries[NAT_JOURNAL_ENTRIES]; + grub_uint8_t reserved[NAT_JOURNAL_RESERVED]; +} GRUB_PACKED; + +struct grub_f2fs_nat_block { + struct grub_f2fs_nat_entry ne[NAT_ENTRY_PER_BLOCK]; +} GRUB_PACKED; + +struct grub_f2fs_dir_entry +{ + grub_uint32_t hash_code; + grub_uint32_t ino; + grub_uint16_t name_len; + grub_uint8_t file_type; +} GRUB_PACKED; + +struct grub_f2fs_inline_dentry +{ + grub_uint8_t dentry_bitmap[INLINE_DENTRY_BITMAP_SIZE]; + grub_uint8_t reserved[INLINE_RESERVED_SIZE]; + struct grub_f2fs_dir_entry dentry[NR_INLINE_DENTRY]; + grub_uint8_t filename[NR_INLINE_DENTRY][F2FS_SLOT_LEN]; +} GRUB_PACKED; + +struct grub_f2fs_dentry_block { + grub_uint8_t dentry_bitmap[SIZE_OF_DENTRY_BITMAP]; + grub_uint8_t reserved[SIZE_OF_RESERVED]; + struct grub_f2fs_dir_entry dentry[NR_DENTRY_IN_BLOCK]; + grub_uint8_t filename[NR_DENTRY_IN_BLOCK][F2FS_SLOT_LEN]; +} GRUB_PACKED; + +struct grub_f2fs_inode +{ + grub_uint16_t i_mode; + grub_uint8_t i_advise; + grub_uint8_t i_inline; + grub_uint32_t i_uid; + grub_uint32_t i_gid; + grub_uint32_t i_links; + grub_uint64_t i_size; + grub_uint64_t i_blocks; + grub_uint64_t i_atime; + grub_uint64_t i_ctime; + grub_uint64_t i_mtime; + grub_uint32_t i_atime_nsec; + grub_uint32_t i_ctime_nsec; + grub_uint32_t i_mtime_nsec; + grub_uint32_t i_generation; + grub_uint32_t i_current_depth; + grub_uint32_t i_xattr_nid; + grub_uint32_t i_flags; + grub_uint32_t i_pino; + grub_uint32_t i_namelen; + grub_uint8_t i_name[F2FS_NAME_LEN]; + grub_uint8_t i_dir_level; + grub_uint8_t i_ext[12]; + grub_uint32_t i_addr[DEF_ADDRS_PER_INODE]; + grub_uint32_t i_nid[5]; +} GRUB_PACKED; + +struct grub_direct_node { + grub_uint32_t addr[ADDRS_PER_BLOCK]; +} GRUB_PACKED; + +struct grub_indirect_node { + grub_uint32_t nid[NIDS_PER_BLOCK]; +} GRUB_PACKED; + +struct grub_f2fs_node +{ + union + { + struct grub_f2fs_inode i; + struct grub_direct_node dn; + struct grub_indirect_node in; + char buf[F2FS_BLKSIZE - 40]; /* Should occupy F2FS_BLKSIZE totally *= / + }; + grub_uint8_t dummy[40]; +} GRUB_PACKED; + +struct grub_fshelp_node +{ + struct grub_f2fs_data *data; + struct grub_f2fs_node inode; + grub_uint32_t ino; + int inode_read; +}; + +struct grub_f2fs_data +{ + struct grub_f2fs_superblock sblock; + struct grub_f2fs_checkpoint ckpt; + + grub_uint32_t root_ino; + grub_uint32_t blocks_per_seg; + grub_uint32_t cp_blkaddr; + grub_uint32_t nat_blkaddr; + + struct grub_f2fs_nat_journal nat_j; + char *nat_bitmap; + + grub_disk_t disk; + struct grub_f2fs_node *inode; + struct grub_fshelp_node diropen; +}; + +struct grub_f2fs_dir_iter_ctx +{ + struct grub_f2fs_data *data; + grub_fshelp_iterate_dir_hook_t hook; + void *hook_data; + grub_uint32_t *bitmap; + grub_uint8_t (*filename)[F2FS_SLOT_LEN]; + struct grub_f2fs_dir_entry *dentry; + int max; +}; + +struct grub_f2fs_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; + struct grub_f2fs_data *data; +}; + +static grub_dl_t my_mod; + +static inline int +grub_generic_test_bit (int nr, const grub_uint32_t *addr) +{ + return 1UL & (addr[nr / 32] >> (nr & 31)); +} + +static inline char * +__inline_addr (struct grub_f2fs_inode *inode) +{ + return (char *)&inode->i_addr[1]; +} + +static inline grub_uint64_t +grub_f2fs_file_size (struct grub_f2fs_inode *inode) +{ + return grub_le_to_cpu64 (inode->i_size); +} + +static inline grub_uint32_t +__start_cp_addr (struct grub_f2fs_data *data) +{ + struct grub_f2fs_checkpoint *ckpt =3D &data->ckpt; + grub_uint64_t ckpt_version =3D grub_le_to_cpu64 (ckpt->checkpoint_ver)= ; + grub_uint32_t start_addr =3D data->cp_blkaddr; + + if (!(ckpt_version & 1)) + return start_addr + data->blocks_per_seg; + return start_addr; +} + +static inline grub_uint32_t +__start_sum_block (struct grub_f2fs_data *data) +{ + struct grub_f2fs_checkpoint *ckpt =3D &data->ckpt; + + return __start_cp_addr (data) + grub_le_to_cpu32 (ckpt->cp_pack_start_= sum); +} + +static inline grub_uint32_t +__sum_blk_addr (struct grub_f2fs_data *data, int base, int type) +{ + struct grub_f2fs_checkpoint *ckpt =3D &data->ckpt; + + return __start_cp_addr (data) + + grub_le_to_cpu32 (ckpt->cp_pack_total_block_count) + - (base + 1) + type; +} + +static inline void * +__nat_bitmap_ptr (struct grub_f2fs_data *data) +{ + struct grub_f2fs_checkpoint *ckpt =3D &data->ckpt; + grub_uint32_t offset; + + if (grub_le_to_cpu32 (data->sblock.cp_payload) > 0) + return ckpt->sit_nat_version_bitmap; + + offset =3D grub_le_to_cpu32 (ckpt->sit_ver_bitmap_bytesize); + return ckpt->sit_nat_version_bitmap + offset; +} + +static inline grub_uint32_t +__get_node_id (struct grub_f2fs_node *rn, int off, int inode_block) +{ + if (inode_block) + return grub_le_to_cpu32 (rn->i.i_nid[off - NODE_DIR1_BLOCK]); + return grub_le_to_cpu32 (rn->in.nid[off]); +} + +static inline grub_err_t +grub_f2fs_block_read (struct grub_f2fs_data *data, grub_uint32_t blkaddr= , void *buf) +{ + return grub_disk_read (data->disk, + ((grub_disk_addr_t)blkaddr) << F2FS_BLK_SEC_BITS, + 0, F2FS_BLKSIZE, buf); +} + +/* + * CRC32 +*/ +#define CRCPOLY_LE 0xedb88320 + +static inline grub_uint32_t +grub_f2fs_cal_crc32 (const void *buf, const grub_uint32_t len) +{ + grub_uint32_t crc =3D F2FS_SUPER_MAGIC; + unsigned char *p =3D (unsigned char *)buf; + grub_uint32_t tmp =3D len; + int i; + + while (tmp--) + { + crc ^=3D *p++; + for (i =3D 0; i < 8; i++) + crc =3D (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); + } + return crc; +} + +static inline int +grub_f2fs_crc_valid (grub_uint32_t blk_crc, void *buf, const grub_uint32= _t len) +{ + grub_uint32_t cal_crc =3D 0; + + cal_crc =3D grub_f2fs_cal_crc32 (buf, len); + + return (cal_crc =3D=3D blk_crc) ? 1 : 0; +} + +static inline int +grub_f2fs_test_bit (grub_uint32_t nr, const char *p) +{ + int mask; + + p +=3D (nr >> 3); + mask =3D 1 << (7 - (nr & 0x07)); + return (mask & *p) !=3D 0; +} + +static int +grub_f2fs_sanity_check_sb (struct grub_f2fs_superblock *sb) +{ + grub_uint32_t log_sectorsize, log_sectors_per_block; + + if (sb->magic !=3D grub_cpu_to_le32_compile_time (F2FS_SUPER_MAGIC)) + return -1; + + if (sb->log_blocksize !=3D grub_cpu_to_le32_compile_time (F2FS_BLK_BIT= S)) + return -1; + + log_sectorsize =3D grub_le_to_cpu32 (sb->log_sectorsize); + log_sectors_per_block =3D grub_le_to_cpu32 (sb->log_sectors_per_block)= ; + + if (log_sectorsize > F2FS_MAX_LOG_SECTOR_SIZE) + return -1; + + if (log_sectorsize < F2FS_MIN_LOG_SECTOR_SIZE) + return -1; + + if (log_sectors_per_block + log_sectorsize !=3D F2FS_MAX_LOG_SECTOR_SI= ZE) + return -1; + + return 0; +} + +static int +grub_f2fs_read_sb (struct grub_f2fs_data *data, grub_disk_addr_t offset) +{ + grub_disk_t disk =3D data->disk; + grub_err_t err; + + /* Read first super block. */ + err =3D grub_disk_read (disk, offset, 0, sizeof (data->sblock), &data-= >sblock); + if (err) + return -1; + + return grub_f2fs_sanity_check_sb (&data->sblock); +} + +static void * +validate_checkpoint (struct grub_f2fs_data *data, grub_uint32_t cp_addr, + grub_uint64_t *version) +{ + void *cp_page_1, *cp_page_2; + struct grub_f2fs_checkpoint *cp_block; + grub_uint64_t cur_version =3D 0, pre_version =3D 0; + grub_uint32_t crc =3D 0; + grub_uint32_t crc_offset; + grub_err_t err; + + /* Read the 1st cp block in this CP pack */ + cp_page_1 =3D grub_malloc (F2FS_BLKSIZE); + if (!cp_page_1) + return NULL; + + err =3D grub_f2fs_block_read (data, cp_addr, cp_page_1); + if (err) + goto invalid_cp1; + + cp_block =3D (struct grub_f2fs_checkpoint *)cp_page_1; + crc_offset =3D grub_le_to_cpu32 (cp_block->checksum_offset); + if (crc_offset !=3D CHECKSUM_OFFSET) + goto invalid_cp1; + + crc =3D grub_le_to_cpu32 (*(grub_uint32_t *)((char *)cp_block + crc_of= fset)); + if (!grub_f2fs_crc_valid (crc, cp_block, crc_offset)) + goto invalid_cp1; + + pre_version =3D grub_le_to_cpu64 (cp_block->checkpoint_ver); + + /* Read the 2nd cp block in this CP pack */ + cp_page_2 =3D grub_malloc (F2FS_BLKSIZE); + if (!cp_page_2) + goto invalid_cp1; + + cp_addr +=3D grub_le_to_cpu32 (cp_block->cp_pack_total_block_count) - = 1; + + err =3D grub_f2fs_block_read (data, cp_addr, cp_page_2); + if (err) + goto invalid_cp2; + + cp_block =3D (struct grub_f2fs_checkpoint *)cp_page_2; + crc_offset =3D grub_le_to_cpu32 (cp_block->checksum_offset); + if (crc_offset !=3D CHECKSUM_OFFSET) + goto invalid_cp2; + + crc =3D grub_le_to_cpu32 (*(grub_uint32_t *)((char *)cp_block + crc_of= fset)); + if (!grub_f2fs_crc_valid (crc, cp_block, crc_offset)) + goto invalid_cp2; + + cur_version =3D grub_le_to_cpu64 (cp_block->checkpoint_ver); + if (cur_version =3D=3D pre_version) + { + *version =3D cur_version; + grub_free (cp_page_2); + return cp_page_1; + } + +invalid_cp2: + grub_free (cp_page_2); +invalid_cp1: + grub_free (cp_page_1); + return NULL; +} + +static grub_err_t +grub_f2fs_read_cp (struct grub_f2fs_data *data) +{ + void *cp1, *cp2, *cur_page; + grub_uint64_t cp1_version =3D 0, cp2_version =3D 0; + grub_uint64_t cp_start_blk_no; + + /* + * Finding out valid cp block involves read both + * sets (cp pack1 and cp pack 2) + */ + cp_start_blk_no =3D data->cp_blkaddr; + cp1 =3D validate_checkpoint (data, cp_start_blk_no, &cp1_version); + if (!cp1 && grub_errno) + return grub_errno; + + /* The second checkpoint pack should start at the next segment */ + cp_start_blk_no +=3D data->blocks_per_seg; + cp2 =3D validate_checkpoint (data, cp_start_blk_no, &cp2_version); + if (!cp2 && grub_errno) + { + grub_free (cp1); + return grub_errno; + } + + if (cp1 && cp2) + cur_page =3D (cp2_version > cp1_version) ? cp2 : cp1; + else if (cp1) + cur_page =3D cp1; + else if (cp2) + cur_page =3D cp2; + else + return grub_error (GRUB_ERR_BAD_FS, "no checkpoints"); + + grub_memcpy (&data->ckpt, cur_page, F2FS_BLKSIZE); + + grub_free (cp1); + grub_free (cp2); + return 0; +} + +static grub_err_t +get_nat_journal (struct grub_f2fs_data *data) +{ + grub_uint32_t block; + char *buf; + grub_err_t err; + + buf =3D grub_malloc (F2FS_BLKSIZE); + if (!buf) + return grub_errno; + + if (CKPT_FLAG_SET(&data->ckpt, CP_COMPACT_SUM_FLAG)) + block =3D __start_sum_block (data); + else if (CKPT_FLAG_SET (&data->ckpt, CP_UMOUNT_FLAG)) + block =3D __sum_blk_addr (data, NR_CURSEG_TYPE, CURSEG_HOT_DATA); + else + block =3D __sum_blk_addr (data, NR_CURSEG_DATA_TYPE, CURSEG_HOT_DATA= ); + + err =3D grub_f2fs_block_read (data, block, buf); + if (err) + goto fail; + + if (CKPT_FLAG_SET (&data->ckpt, CP_COMPACT_SUM_FLAG)) + grub_memcpy (&data->nat_j, buf, SUM_JOURNAL_SIZE); + else + grub_memcpy (&data->nat_j, buf + SUM_ENTRIES_SIZE, SUM_JOURNAL_SIZE)= ; + +fail: + grub_free (buf); + return err; +} + +static grub_uint32_t +get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t= nid) +{ + grub_uint16_t n =3D grub_le_to_cpu16 (data->nat_j.n_nats); + grub_uint32_t blkaddr =3D 0; + grub_uint16_t i; + + for (i =3D 0; i < n; i++) + { + if (grub_le_to_cpu32 (data->nat_j.entries[i].nid) =3D=3D nid) + { + blkaddr =3D grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_= addr); + break; + } + } + return blkaddr; +} + +static grub_uint32_t +get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid) +{ + struct grub_f2fs_nat_block *nat_block; + grub_uint32_t seg_off, block_off, entry_off, block_addr; + grub_uint32_t blkaddr; + grub_err_t err; + + blkaddr =3D get_blkaddr_from_nat_journal (data, nid); + if (blkaddr) + return blkaddr; + + nat_block =3D grub_malloc (F2FS_BLKSIZE); + if (!nat_block) + return 0; + + block_off =3D nid / NAT_ENTRY_PER_BLOCK; + entry_off =3D nid % NAT_ENTRY_PER_BLOCK; + + seg_off =3D block_off / data->blocks_per_seg; + block_addr =3D data->nat_blkaddr + + ((seg_off * data->blocks_per_seg) << 1) + + (block_off & (data->blocks_per_seg - 1)); + + if (grub_f2fs_test_bit (block_off, data->nat_bitmap)) + block_addr +=3D data->blocks_per_seg; + + err =3D grub_f2fs_block_read (data, block_addr, nat_block); + if (err) + { + grub_free (nat_block); + return 0; + } + + blkaddr =3D grub_le_to_cpu32 (nat_block->ne[entry_off].block_addr); + + grub_free (nat_block); + + return blkaddr; +} + +static int +grub_get_node_path (struct grub_f2fs_inode *inode, grub_uint32_t block, + grub_uint32_t offset[4], grub_uint32_t noffset[4]) +{ + grub_uint32_t direct_blks =3D ADDRS_PER_BLOCK; + grub_uint32_t dptrs_per_blk =3D NIDS_PER_BLOCK; + grub_uint32_t indirect_blks =3D ADDRS_PER_BLOCK * NIDS_PER_BLOCK; + grub_uint32_t dindirect_blks =3D indirect_blks * NIDS_PER_BLOCK; + grub_uint32_t direct_index =3D DEF_ADDRS_PER_INODE; + int n =3D 0; + int level =3D 0; + + if (inode->i_inline & F2FS_INLINE_XATTR) + direct_index -=3D F2FS_INLINE_XATTR_ADDRS; + + noffset[0] =3D 0; + + if (block < direct_index) + { + offset[n] =3D block; + goto got; + } + + block -=3D direct_index; + if (block < direct_blks) + { + offset[n++] =3D NODE_DIR1_BLOCK; + noffset[n] =3D 1; + offset[n] =3D block; + level =3D 1; + goto got; + } + + block -=3D direct_blks; + if (block < direct_blks) + { + offset[n++] =3D NODE_DIR2_BLOCK; + noffset[n] =3D 2; + offset[n] =3D block; + level =3D 1; + goto got; + } + + block -=3D direct_blks; + if (block < indirect_blks) + { + offset[n++] =3D NODE_IND1_BLOCK; + noffset[n] =3D 3; + offset[n++] =3D block / direct_blks; + noffset[n] =3D 4 + offset[n - 1]; + offset[n] =3D block % direct_blks; + level =3D 2; + goto got; + } + + block -=3D indirect_blks; + if (block < indirect_blks) + { + offset[n++] =3D NODE_IND2_BLOCK; + noffset[n] =3D 4 + dptrs_per_blk; + offset[n++] =3D block / direct_blks; + noffset[n] =3D 5 + dptrs_per_blk + offset[n - 1]; + offset[n] =3D block % direct_blks; + level =3D 2; + goto got; + } + + block -=3D indirect_blks; + if (block < dindirect_blks) + { + offset[n++] =3D NODE_DIND_BLOCK; + noffset[n] =3D 5 + (dptrs_per_blk * 2); + offset[n++] =3D block / indirect_blks; + noffset[n] =3D 6 + (dptrs_per_blk * 2) + + offset[n - 1] * (dptrs_per_blk + 1); + offset[n++] =3D (block / direct_blks) % dptrs_per_blk; + noffset[n] =3D 7 + (dptrs_per_blk * 2) + + offset[n - 2] * (dptrs_per_blk + 1) + offset[n - 1]; + offset[n] =3D block % direct_blks; + level =3D 3; + goto got; + } +got: + return level; +} + +static grub_err_t +grub_f2fs_read_node (struct grub_f2fs_data *data, + grub_uint32_t nid, struct grub_f2fs_node *np) +{ + grub_uint32_t blkaddr; + + blkaddr =3D get_node_blkaddr (data, nid); + if (!blkaddr) + return grub_errno; + + return grub_f2fs_block_read (data, blkaddr, np); +} + +static struct grub_f2fs_data * +grub_f2fs_mount (grub_disk_t disk) +{ + struct grub_f2fs_data *data; + grub_err_t err; + + data =3D grub_malloc (sizeof (*data)); + if (!data) + return NULL; + + data->disk =3D disk; + + if (grub_f2fs_read_sb (data, F2FS_SUPER_OFFSET0)) + { + if (grub_f2fs_read_sb (data, F2FS_SUPER_OFFSET1)) + { + if (grub_errno =3D=3D GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_FS, + "not a F2FS filesystem (no superblock)"); + goto fail; + } + } + + data->root_ino =3D grub_le_to_cpu32 (data->sblock.root_ino); + data->cp_blkaddr =3D grub_le_to_cpu32 (data->sblock.cp_blkaddr); + data->nat_blkaddr =3D grub_le_to_cpu32 (data->sblock.nat_blkaddr); + data->blocks_per_seg =3D 1 << + grub_le_to_cpu32 (data->sblock.log_blocks_per_seg); + + err =3D grub_f2fs_read_cp (data); + if (err) + goto fail; + + data->nat_bitmap =3D __nat_bitmap_ptr (data); + + err =3D get_nat_journal (data); + if (err) + goto fail; + + data->diropen.data =3D data; + data->diropen.ino =3D data->root_ino; + data->diropen.inode_read =3D 1; + data->inode =3D &data->diropen.inode; + + err =3D grub_f2fs_read_node (data, data->root_ino, data->inode); + if (err) + goto fail; + + return data; + +fail: + grub_free (data); + return NULL; +} + +/* guarantee inline_data was handled by caller */ +static grub_disk_addr_t +grub_f2fs_get_block (grub_fshelp_node_t node, grub_disk_addr_t block_ofs= ) +{ + struct grub_f2fs_data *data =3D node->data; + struct grub_f2fs_inode *inode =3D &node->inode.i; + grub_uint32_t offset[4], noffset[4], nids[4]; + struct grub_f2fs_node *node_block; + grub_uint32_t block_addr =3D -1; + int level, i; + + level =3D grub_get_node_path (inode, block_ofs, offset, noffset); + if (level =3D=3D 0) + return grub_le_to_cpu32 (inode->i_addr[offset[0]]); + + node_block =3D grub_malloc (F2FS_BLKSIZE); + if (!node_block) + return -1; + + nids[1] =3D __get_node_id (&node->inode, offset[0], 1); + + /* get indirect or direct nodes */ + for (i =3D 1; i <=3D level; i++) + { + grub_f2fs_read_node (data, nids[i], node_block); + if (grub_errno) + goto fail; + + if (i < level) + nids[i + 1] =3D __get_node_id (node_block, offset[i], 0); + } + + block_addr =3D grub_le_to_cpu32 (node_block->dn.addr[offset[level]]); +fail: + grub_free (node_block); + return block_addr; +} + +static grub_ssize_t +grub_f2fs_read_file (grub_fshelp_node_t node, + grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) +{ + struct grub_f2fs_inode *inode =3D &node->inode.i; + grub_off_t filesize =3D grub_f2fs_file_size (inode); + char *inline_addr =3D __inline_addr (inode); + + if (inode->i_inline & F2FS_INLINE_DATA) + { + if (pos > filesize || filesize > MAX_INLINE_DATA) + { + grub_error (GRUB_ERR_BAD_FS, "corrupted inline_data: need fsck= "); + return -1; + } + if (len > filesize - pos) + len =3D filesize - pos; + + grub_memcpy (buf + pos, inline_addr + pos, len); + return len; + } + + return grub_fshelp_read_file (node->data->disk, node, + read_hook, read_hook_data, + pos, len, buf, grub_f2fs_get_block, + filesize, + F2FS_BLK_SEC_BITS, 0); +} + +static char * +grub_f2fs_read_symlink (grub_fshelp_node_t node) +{ + char *symlink; + struct grub_fshelp_node *diro =3D node; + grub_uint64_t filesize; + + if (!diro->inode_read) + { + grub_f2fs_read_node (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + filesize =3D grub_f2fs_file_size(&diro->inode.i); + + symlink =3D grub_malloc (filesize + 1); + if (!symlink) + return 0; + + grub_f2fs_read_file (diro, 0, 0, 0, filesize, symlink); + if (grub_errno) + { + grub_free (symlink); + return 0; + } + + symlink[filesize] =3D '\0'; + return symlink; +} + +static int +grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx) +{ + struct grub_fshelp_node *fdiro; + int i; + + for (i =3D 0; i < ctx->max;) + { + char *filename; + enum grub_fshelp_filetype type =3D GRUB_FSHELP_UNKNOWN; + enum FILE_TYPE ftype; + int name_len; + int ret; + + if (grub_generic_test_bit (i, ctx->bitmap) =3D=3D 0) + { + i++; + continue; + } + + ftype =3D ctx->dentry[i].file_type; + name_len =3D grub_le_to_cpu16 (ctx->dentry[i].name_len); + filename =3D grub_malloc (name_len + 1); + if (!filename) + return 0; + + grub_memcpy (filename, ctx->filename[i], name_len); + filename[name_len] =3D 0; + + fdiro =3D grub_malloc (sizeof (struct grub_fshelp_node)); + if (!fdiro) + { + grub_free(filename); + return 0; + } + + if (ftype =3D=3D F2FS_FT_DIR) + type =3D GRUB_FSHELP_DIR; + else if (ftype =3D=3D F2FS_FT_SYMLINK) + type =3D GRUB_FSHELP_SYMLINK; + else if (ftype =3D=3D F2FS_FT_REG_FILE) + type =3D GRUB_FSHELP_REG; + + fdiro->data =3D ctx->data; + fdiro->ino =3D grub_le_to_cpu32 (ctx->dentry[i].ino); + fdiro->inode_read =3D 0; + + ret =3D ctx->hook (filename, type, fdiro, ctx->hook_data); + grub_free(filename); + if (ret) + return 1; + + i +=3D (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; + } + return 0; +} + +static int +grub_f2fs_iterate_inline_dir (struct grub_f2fs_inode *dir, + struct grub_f2fs_dir_iter_ctx *ctx) +{ + struct grub_f2fs_inline_dentry *de_blk; + + de_blk =3D (struct grub_f2fs_inline_dentry *) __inline_addr (dir); + + ctx->bitmap =3D (grub_uint32_t *) de_blk->dentry_bitmap; + ctx->dentry =3D de_blk->dentry; + ctx->filename =3D de_blk->filename; + ctx->max =3D NR_INLINE_DENTRY; + + return grub_f2fs_check_dentries (ctx); +} + +static int +grub_f2fs_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + struct grub_fshelp_node *diro =3D (struct grub_fshelp_node *) dir; + struct grub_f2fs_inode *inode; + struct grub_f2fs_dir_iter_ctx ctx =3D { + .data =3D diro->data, + .hook =3D hook, + .hook_data =3D hook_data + }; + grub_off_t fpos =3D 0; + + if (!diro->inode_read) + { + grub_f2fs_read_node (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + inode =3D &diro->inode.i; + + if (inode->i_inline & F2FS_INLINE_DENTRY) + return grub_f2fs_iterate_inline_dir (inode, &ctx); + + while (fpos < grub_f2fs_file_size (inode)) + { + struct grub_f2fs_dentry_block *de_blk; + char *buf; + int ret; + + buf =3D grub_zalloc (F2FS_BLKSIZE); + if (!buf) + return 0; + + grub_f2fs_read_file (diro, 0, 0, fpos, F2FS_BLKSIZE, buf); + if (grub_errno) + { + grub_free (buf); + return 0; + } + + de_blk =3D (struct grub_f2fs_dentry_block *) buf; + + ctx.bitmap =3D (grub_uint32_t *) de_blk->dentry_bitmap; + ctx.dentry =3D de_blk->dentry; + ctx.filename =3D de_blk->filename; + ctx.max =3D NR_DENTRY_IN_BLOCK; + + ret =3D grub_f2fs_check_dentries (&ctx); + grub_free (buf); + if (ret) + return 1; + + fpos +=3D F2FS_BLKSIZE; + } + return 0; +} + +static int +grub_f2fs_dir_iter (const char *filename, enum grub_fshelp_filetype file= type, + grub_fshelp_node_t node, void *data) +{ + struct grub_f2fs_dir_ctx *ctx =3D data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + if (!node->inode_read) + { + grub_f2fs_read_node (ctx->data, node->ino, &node->inode); + if (!grub_errno) + node->inode_read =3D 1; + grub_errno =3D GRUB_ERR_NONE; + } + if (node->inode_read) + { + info.mtimeset =3D 1; + info.mtime =3D grub_le_to_cpu64 (node->inode.i.i_mtime); + } + + info.dir =3D ((filetype & GRUB_FSHELP_TYPE_MASK) =3D=3D GRUB_FSHELP_DI= R); + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_f2fs_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_f2fs_dir_ctx ctx =3D { + .hook =3D hook, + .hook_data =3D hook_data + }; + struct grub_fshelp_node *fdiro =3D 0; + + grub_dl_ref (my_mod); + + ctx.data =3D grub_f2fs_mount (device->disk); + if (!ctx.data) + goto fail; + + grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro, + grub_f2fs_iterate_dir, grub_f2fs_read_symlink, + GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_f2fs_iterate_dir (fdiro, grub_f2fs_dir_iter, &ctx); + +fail: + if (fdiro !=3D &ctx.data->diropen) + grub_free (fdiro); + grub_free (ctx.data); + grub_dl_unref (my_mod); + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_f2fs_open (struct grub_file *file, const char *name) +{ + struct grub_f2fs_data *data =3D NULL; + struct grub_fshelp_node *fdiro =3D 0; + + grub_dl_ref (my_mod); + + data =3D grub_f2fs_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, + grub_f2fs_iterate_dir, grub_f2fs_read_symlink, + GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + if (!fdiro->inode_read) + { + grub_f2fs_read_node (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } + + grub_memcpy (data->inode, &fdiro->inode, sizeof (*data->inode)); + grub_free (fdiro); + + file->size =3D grub_f2fs_file_size (&(data->inode->i)); + file->data =3D data; + file->offset =3D 0; + + return 0; + +fail: + if (fdiro !=3D &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_ssize_t +grub_f2fs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_f2fs_data *data =3D (struct grub_f2fs_data *) file->data; + + return grub_f2fs_read_file (&data->diropen, + file->read_hook, file->read_hook_data, + file->offset, len, buf); +} + +static grub_err_t +grub_f2fs_close (grub_file_t file) +{ + struct grub_f2fs_data *data =3D (struct grub_f2fs_data *) file->data; + + grub_free (data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +/* TODO: mkfs.f2fs stores label in a wrong way. Should be fixed. */ +static void +grub_f2fs_unicode_to_ascii (grub_uint8_t *out_buf, grub_uint16_t *in_buf= ) +{ + grub_uint16_t *pchTempPtr =3D in_buf; + grub_uint8_t *pwTempPtr =3D out_buf; + + while (*pchTempPtr !=3D '\0') + { + *pwTempPtr =3D (grub_uint8_t) *pchTempPtr; + pchTempPtr++; + pwTempPtr++; + } + *pwTempPtr =3D '\0'; + return; +} + +static grub_err_t +grub_f2fs_label (grub_device_t device, char **label) +{ + struct grub_f2fs_data *data; + grub_disk_t disk =3D device->disk; + + grub_dl_ref (my_mod); + + data =3D grub_f2fs_mount (disk); + if (data) + { + *label =3D grub_zalloc (sizeof (data->sblock.volume_name)); + if (*label) + grub_f2fs_unicode_to_ascii ((grub_uint8_t *) (*label), + data->sblock.volume_name); + } + else + *label =3D NULL; + + grub_free (data); + grub_dl_unref (my_mod); + return grub_errno; +} + +static grub_err_t +grub_f2fs_uuid (grub_device_t device, char **uuid) +{ + struct grub_f2fs_data *data; + grub_disk_t disk =3D device->disk; + + grub_dl_ref (my_mod); + + data =3D grub_f2fs_mount (disk); + if (data) + { + *uuid =3D + grub_xasprintf + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"= , + data->sblock.uuid[0], data->sblock.uuid[1], + data->sblock.uuid[2], data->sblock.uuid[3], + data->sblock.uuid[4], data->sblock.uuid[5], + data->sblock.uuid[6], data->sblock.uuid[7], + data->sblock.uuid[8], data->sblock.uuid[9], + data->sblock.uuid[10], data->sblock.uuid[11], + data->sblock.uuid[12], data->sblock.uuid[13], + data->sblock.uuid[14], data->sblock.uuid[15]); + } + else + *uuid =3D NULL; + + grub_free (data); + grub_dl_unref (my_mod); + return grub_errno; +} + +static struct grub_fs grub_f2fs_fs =3D { + .name =3D "f2fs", + .dir =3D grub_f2fs_dir, + .open =3D grub_f2fs_open, + .read =3D grub_f2fs_read, + .close =3D grub_f2fs_close, + .label =3D grub_f2fs_label, + .uuid =3D grub_f2fs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector =3D 1, + .blocklist_install =3D 0, +#endif + .next =3D 0 +}; + +GRUB_MOD_INIT (f2fs) +{ + grub_fs_register (&grub_f2fs_fs); + my_mod =3D mod; +} + +GRUB_MOD_FINI (f2fs) +{ + grub_fs_unregister (&grub_f2fs_fs); +} diff --git a/po/exclude.pot b/po/exclude.pot index 0a9b215..816089c 100644 --- a/po/exclude.pot +++ b/po/exclude.pot @@ -1214,6 +1214,7 @@ msgstr "" =20 #: grub-core/commands/xnu_uuid.c:75 grub-core/fs/jfs.c:924 #: grub-core/fs/nilfs2.c:1135 +#: grub-core/fs/f2fs.c:1259 #, c-format msgid "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%= 02x" msgstr "" diff --git a/tests/f2fs_test.in b/tests/f2fs_test.in new file mode 100644 index 0000000..1ea77c8 --- /dev/null +++ b/tests/f2fs_test.in @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" =3D "x" ] ; then + EUID=3D`id -u` +fi + +if [ "$EUID" !=3D 0 ] ; then + exit 77 +fi + +if ! which mkfs.f2fs >/dev/null 2>&1; then + echo "mkfs.f2fs not installed; cannot test f2fs." + exit 77 +fi + + +"@builddir@/grub-fs-tester" f2fs diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in index 424de22..7245cb8 100644 --- a/tests/util/grub-fs-tester.in +++ b/tests/util/grub-fs-tester.in @@ -142,7 +142,7 @@ for ((LOGSECSIZE=3DMINLOGSECSIZE;LOGSECSIZE<=3DMAXLOG= SECSIZE;LOGSECSIZE=3DLOGSECSIZE + xsquash*) MINBLKSIZE=3D4096 MAXBLKSIZE=3D1048576;; - xxfs) + xxfs|xf2fs) MINBLKSIZE=3D$SECSIZE # OS Limitation: GNU/Linux doesn't accept > 4096 MAXBLKSIZE=3D4096;; @@ -265,6 +265,11 @@ for ((LOGSECSIZE=3DMINLOGSECSIZE;LOGSECSIZE<=3DMAXLO= GSECSIZE;LOGSECSIZE=3DLOGSECSIZE + x"btrfs"*) FSLABEL=3D"grub_;/test=C3=A9=F0=AF=A6=9B=F0=AF=A6=9D=F0=9F=98=81=D0= =BA=D0=B8=D1=80=D0=B8=D1=82i urewfceniuewruevrewnuuireurevueurnievrewfner= fcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvew= nvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoir= oireoireoifrefoieroifoireoif";; =20 + # FS LIMITATION: f2fs label is at most 512 UTF-16 chars + # TODO: seems that mkfs.f2fs doesn't handle encoding stuffs correct= ly + x"f2fs") + FSLABEL=3D"grub_test:no utf16";; + # FS LIMITATION: exfat is at most 15 UTF-16 chars x"exfat") FSLABEL=3D"g=C3=A9=D1=82 ;/=F0=AF=A6=9B=F0=AF=A6=9D=F0=9F=98=81=D0= =BA=D0=B8=D1=80";; @@ -474,7 +479,7 @@ for ((LOGSECSIZE=3DMINLOGSECSIZE;LOGSECSIZE<=3DMAXLOG= SECSIZE;LOGSECSIZE=3DLOGSECSIZE + # FIXME: Not sure about BtrFS, NTFS, JFS, AFS, UDF and SFS. Check i= t. # FS LIMITATION: as far as I know those FS don't store their last modif= ication date. x"jfs_caseins" | x"jfs" | x"xfs" | x"xfs_crc" | x"btrfs"* | x"reiserfs= _old" | x"reiserfs" \ - | x"bfs" | x"afs" \ + | x"bfs" | x"afs" | x"f2fs" \ | x"tarfs" | x"cpio_"* | x"minix" | x"minix2" \ | x"minix3" | x"ntfs"* | x"udf" | x"sfs"*) NOFSTIME=3Dy;; @@ -753,6 +758,8 @@ for ((LOGSECSIZE=3DMINLOGSECSIZE;LOGSECSIZE<=3DMAXLOG= SECSIZE;LOGSECSIZE=3DLOGSECSIZE + MOUNTDEVICE=3D"/dev/mapper/grub_test-testvol" MOUNTFS=3Dext2 "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;; + xf2fs) + "mkfs.f2fs" -l "$FSLABEL" -q "${LODEVICES[0]}" ;; xnilfs2) "mkfs.nilfs2" -L "$FSLABEL" -b $BLKSIZE -q "${LODEVICES[0]}" ;; xext2_old) --=20 2.4.9 (Apple Git-60) From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jaegeuk Kim Subject: Re: [PATCH v3] F2FS support Date: Fri, 20 Nov 2015 05:28:24 +0800 Message-ID: <20151119212824.GA11666@jaegeuk.local> References: <1427185140-41120-1-git-send-email-jaegeuk@kernel.org> <20150403224908.GB25673@jaegeuk-mac02.mot.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from sog-mx-2.v43.ch3.sourceforge.com ([172.29.43.192] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ZzWl4-0000N1-IL for linux-f2fs-devel@lists.sourceforge.net; Thu, 19 Nov 2015 21:28:46 +0000 Received: from mail.kernel.org ([198.145.29.136]) by sog-mx-2.v43.ch3.sourceforge.com with esmtp (Exim 4.76) id 1ZzWl1-0007f5-2f for linux-f2fs-devel@lists.sourceforge.net; Thu, 19 Nov 2015 21:28:46 +0000 Content-Disposition: inline In-Reply-To: <20150403224908.GB25673@jaegeuk-mac02.mot.com> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net To: grub-devel@gnu.org, linux-f2fs-devel@lists.sourceforge.net SGVsbG8sCgpDaGFuZ2UgbG9nIGZyb20gdjI6CiBvIEVuaGFuY2UgdGhlIGNvZGUgcXVhbGl0eSBz dWdnZXN0ZWQgYnkgQW5kcmVpCgpTb3JyeSBmb3IgdGhlIGxvbmcgZGVsYXkuCkNvdWxkIHlvdSBw bGVhc2UgY2hlY2sgdGhpcyBwYXRjaD8KClRoYW5rIHlvdSBzbyBtdWNoLAoKLS0tID4mIC0tLQpG cm9tIDJjMGUxZDMzNTMzZmM5ZmIyNjg2ZjBlMmMxN2VmY2ExMWNlNTdlMmYgTW9uIFNlcCAxNyAw MDowMDowMCAyMDAxCkZyb206IEphZWdldWsgS2ltIDxqYWVnZXVrQGtlcm5lbC5vcmc+CkRhdGU6 IFR1ZSwgMTcgTm92IDIwMTUgMTI6NDU6MTMgLTA4MDAKU3ViamVjdDogW1BBVENIXSBGMkZTIHN1 cHBvcnQKCiJGMkZTIChGbGFzaC1GcmllbmRseSBGaWxlIFN5c3RlbSkgaXMgZmxhc2gtZnJpZW5k bHkgZmlsZSBzeXN0ZW0gd2hpY2ggd2FzIG1lcmdlZAppbnRvIExpbnV4IGtlcm5lbCB2My44IGlu IDIwMTMuCgpUaGUgbW90aXZlIGZvciBGMkZTIHdhcyB0byBidWlsZCBhIGZpbGUgc3lzdGVtIHRo YXQgZnJvbSB0aGUgc3RhcnQsIHRha2VzIGludG8KYWNjb3VudCB0aGUgY2hhcmFjdGVyaXN0aWNz IG9mIE5BTkQgZmxhc2ggbWVtb3J5LWJhc2VkIHN0b3JhZ2UgZGV2aWNlcyAoc3VjaCBhcwpzb2xp ZC1zdGF0ZSBkaXNrcywgZU1NQywgYW5kIFNEIGNhcmRzKS4KCkYyRlMgd2FzIGRlc2lnbmVkIG9u IGEgYmFzaXMgb2YgYSBsb2ctc3RydWN0dXJlZCBmaWxlIHN5c3RlbSBhcHByb2FjaCwgd2hpY2gK cmVtZWRpZXMgc29tZSBrbm93biBpc3N1ZXMgb2YgdGhlIG9sZGVyIGxvZyBzdHJ1Y3R1cmVkIGZp bGUgc3lzdGVtcywgc3VjaCBhcwp0aGUgc25vd2JhbGwgZWZmZWN0IG9mIHdhbmRlcmluZyB0cmVl cyBhbmQgaGlnaCBjbGVhbmluZyBvdmVyaGVhZC4gSW4gYWRkaXRpb24sCnNpbmNlIGEgTkFORC1i YXNlZCBzdG9yYWdlIGRldmljZSBzaG93cyBkaWZmZXJlbnQgY2hhcmFjdGVyaXN0aWNzIGFjY29y ZGluZyB0bwppdHMgaW50ZXJuYWwgZ2VvbWV0cnkgb3IgZmxhc2ggbWVtb3J5IG1hbmFnZW1lbnQg c2NoZW1lIChzdWNoIGFzIHRoZSBGbGFzaApUcmFuc2xhdGlvbiBMYXllciBvciBGVEwpLCBpdCBz dXBwb3J0cyB2YXJpb3VzIHBhcmFtZXRlcnMgbm90IG9ubHkgZm9yCmNvbmZpZ3VyaW5nIG9uLWRp c2sgbGF5b3V0LCBidXQgYWxzbyBmb3Igc2VsZWN0aW5nIGFsbG9jYXRpb24gYW5kIGNsZWFuaW5n CmFsZ29yaXRobS4iLCBxdW90ZSBieSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GMkZT LgoKVGhlIHNvdXJjZSBjb2RlcyBmb3IgRjJGUyBhcmUgYXZhaWxhYmxlIGZyb206CgpodHRwOi8v Z2l0Lmtlcm5lbC5vcmcvY2dpdC9saW51eC9rZXJuZWwvZ2l0L2phZWdldWsvZjJmcy5naXQKaHR0 cDovL2dpdC5rZXJuZWwub3JnL2NnaXQvbGludXgva2VybmVsL2dpdC9qYWVnZXVrL2YyZnMtdG9v bHMuZ2l0CgpTaWduZWQtb2ZmLWJ5OiBKYWVnZXVrIEtpbSA8amFlZ2V1a0BrZXJuZWwub3JnPgot LS0KIE1ha2VmaWxlLnV0aWwuZGVmICAgICAgICAgICAgfCAgICA3ICsKIGRvY3MvZ3J1Yi50ZXhp ICAgICAgICAgICAgICAgfCAgICA1ICstCiBncnViLWNvcmUvTWFrZWZpbGUuY29yZS5kZWYgIHwg ICAgNSArCiBncnViLWNvcmUvZnMvZjJmcy5jICAgICAgICAgIHwgMTI5MSArKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysKIHBvL2V4Y2x1ZGUucG90ICAgICAgICAgICAg ICAgfCAgICAxICsKIHRlc3RzL2YyZnNfdGVzdC5pbiAgICAgICAgICAgfCAgIDE5ICsKIHRlc3Rz L3V0aWwvZ3J1Yi1mcy10ZXN0ZXIuaW4gfCAgIDExICstCiA3IGZpbGVzIGNoYW5nZWQsIDEzMzUg aW5zZXJ0aW9ucygrKSwgNCBkZWxldGlvbnMoLSkKIGNyZWF0ZSBtb2RlIDEwMDY0NCBncnViLWNv cmUvZnMvZjJmcy5jCiBjcmVhdGUgbW9kZSAxMDA2NDQgdGVzdHMvZjJmc190ZXN0LmluCgpkaWZm IC0tZ2l0IGEvTWFrZWZpbGUudXRpbC5kZWYgYi9NYWtlZmlsZS51dGlsLmRlZgppbmRleCBkYjdl OGVjLi44NDYyN2JiIDEwMDY0NAotLS0gYS9NYWtlZmlsZS51dGlsLmRlZgorKysgYi9NYWtlZmls ZS51dGlsLmRlZgpAQCAtOTksNiArOTksNyBAQCBsaWJyYXJ5ID0gewogICBjb21tb24gPSBncnVi LWNvcmUvZnMvZXh0Mi5jOwogICBjb21tb24gPSBncnViLWNvcmUvZnMvZmF0LmM7CiAgIGNvbW1v biA9IGdydWItY29yZS9mcy9leGZhdC5jOworICBjb21tb24gPSBncnViLWNvcmUvZnMvZjJmcy5j OwogICBjb21tb24gPSBncnViLWNvcmUvZnMvZnNoZWxwLmM7CiAgIGNvbW1vbiA9IGdydWItY29y ZS9mcy9oZnMuYzsKICAgY29tbW9uID0gZ3J1Yi1jb3JlL2ZzL2hmc3BsdXMuYzsKQEAgLTc2Niw2 ICs3NjcsMTIgQEAgc2NyaXB0ID0gewogCiBzY3JpcHQgPSB7CiAgIHRlc3RjYXNlOworICBuYW1l ID0gZjJmc190ZXN0OworICBjb21tb24gPSB0ZXN0cy9mMmZzX3Rlc3QuaW47Cit9OworCitzY3Jp cHQgPSB7CisgIHRlc3RjYXNlOwogICBuYW1lID0gbmlsZnMyX3Rlc3Q7CiAgIGNvbW1vbiA9IHRl c3RzL25pbGZzMl90ZXN0LmluOwogfTsKZGlmZiAtLWdpdCBhL2RvY3MvZ3J1Yi50ZXhpIGIvZG9j cy9ncnViLnRleGkKaW5kZXggMWRmM2RiMi4uZTVhODBmMyAxMDA2NDQKLS0tIGEvZG9jcy9ncnVi LnRleGkKKysrIGIvZG9jcy9ncnViLnRleGkKQEAgLTM2MCw3ICszNjAsOCBAQCBibG9ja2xpc3Qg bm90YXRpb24uIFRoZSBjdXJyZW50bHkgc3VwcG9ydGVkIGZpbGVzeXN0ZW0gdHlwZXMgYXJlIEBk Zm57QW1pZ2EKIEZhc3QgRmlsZVN5c3RlbSAoQUZGUyl9LCBAZGZue0F0aGVPUyBmc30sIEBkZm57 QmVGU30sCiBAZGZue0J0ckZTfSAoaW5jbHVkaW5nIHJhaWQwLCByYWlkMSwgcmFpZDEwLCBnemlw IGFuZCBsem8pLAogQGRmbntjcGlvfSAobGl0dGxlLSBhbmQgYmlnLWVuZGlhbiBiaW4sIG9kYyBh bmQgbmV3YyB2YXJpYW50cyksCi1AZGZue0xpbnV4IGV4dDIvZXh0My9leHQ0fSwgQGRmbntET1Mg RkFUMTIvRkFUMTYvRkFUMzJ9LCBAZGZue2V4RkFUfSwgQGRmbntIRlN9LAorQGRmbntMaW51eCBl eHQyL2V4dDMvZXh0NH0sIEBkZm57RE9TIEZBVDEyL0ZBVDE2L0ZBVDMyfSwgQGRmbntleEZBVH0s CitAZGZue2YyZnN9LCBAZGZue0hGU30sCiBAZGZue0hGUyt9LCBAZGZue0lTTzk2NjB9IChpbmNs dWRpbmcgSm9saWV0LCBSb2NrLXJpZGdlIGFuZCBtdWx0aS1jaHVuayBmaWxlcyksCiBAZGZue0pG U30sIEBkZm57TWluaXggZnN9ICh2ZXJzaW9ucyAxLCAyIGFuZCAzKSwgQGRmbntuaWxmczJ9LAog QGRmbntOVEZTfSAoaW5jbHVkaW5nIGNvbXByZXNzaW9uKSwgQGRmbntSZWlzZXJGU30sIEBkZm57 Uk9NRlN9LApAQCAtNTM0Nyw3ICs1MzQ4LDcgQEAgTlRGUywgSkZTLCBVREYsIEhGUyssIGV4RkFU LCBsb25nIGZpbGVuYW1lcyBpbiBGQVQsIEpvbGlldCBwYXJ0IG9mCiBJU085NjYwIGFyZSB0cmVh dGVkIGFzIFVURi0xNiBhcyBwZXIgc3BlY2lmaWNhdGlvbi4gQUZTIGFuZCBCRlMgYXJlIHJlYWQK IGFzIFVURi04LCBhZ2FpbiBhY2NvcmRpbmcgdG8gc3BlY2lmaWNhdGlvbi4gQnRyRlMsIGNwaW8s IHRhciwgc3F1YXNoNCwgbWluaXgsCiBtaW5peDIsIG1pbml4MywgUk9NRlMsIFJlaXNlckZTLCBY RlMsIGV4dDIsIGV4dDMsIGV4dDQsIEZBVCAoc2hvcnQgbmFtZXMpLAotUm9ja1JpZGdlIHBhcnQg b2YgSVNPOTY2MCwgbmlsZnMyLCBVRlMxLCBVRlMyIGFuZCBaRlMgYXJlIGFzc3VtZWQKK2YyZnMs IFJvY2tSaWRnZSBwYXJ0IG9mIElTTzk2NjAsIG5pbGZzMiwgVUZTMSwgVUZTMiBhbmQgWkZTIGFy ZSBhc3N1bWVkCiB0byBiZSBVVEYtOC4gVGhpcyBtaWdodCBiZSBmYWxzZSBvbiBzeXN0ZW1zIGNv bmZpZ3VyZWQgd2l0aCBsZWdhY3kgY2hhcnNldAogYnV0IGFzIGxvbmcgYXMgdGhlIGNoYXJzZXQg dXNlZCBpcyBzdXBlcnNldCBvZiBBU0NJSSB5b3Ugc2hvdWxkIGJlIGFibGUgdG8KIGFjY2VzcyBB U0NJSS1uYW1lZCBmaWxlcy4gQW5kIGl0J3MgcmVjb21tZW5kZWQgdG8gY29uZmlndXJlIHlvdXIg c3lzdGVtIHRvIHVzZQpkaWZmIC0tZ2l0IGEvZ3J1Yi1jb3JlL01ha2VmaWxlLmNvcmUuZGVmIGIv Z3J1Yi1jb3JlL01ha2VmaWxlLmNvcmUuZGVmCmluZGV4IGQ5ZmEwZTMuLmI1ODVhZGUgMTAwNjQ0 Ci0tLSBhL2dydWItY29yZS9NYWtlZmlsZS5jb3JlLmRlZgorKysgYi9ncnViLWNvcmUvTWFrZWZp bGUuY29yZS5kZWYKQEAgLTEyNzgsNiArMTI3OCwxMSBAQCBtb2R1bGUgPSB7CiB9OwogCiBtb2R1 bGUgPSB7CisgIG5hbWUgPSBmMmZzOworICBjb21tb24gPSBmcy9mMmZzLmM7Cit9OworCittb2R1 bGUgPSB7CiAgIG5hbWUgPSBmc2hlbHA7CiAgIGNvbW1vbiA9IGZzL2ZzaGVscC5jOwogfTsKZGlm ZiAtLWdpdCBhL2dydWItY29yZS9mcy9mMmZzLmMgYi9ncnViLWNvcmUvZnMvZjJmcy5jCm5ldyBm aWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmMGFkZDgKLS0tIC9kZXYvbnVsbAorKysg Yi9ncnViLWNvcmUvZnMvZjJmcy5jCkBAIC0wLDAgKzEsMTI5MSBAQAorLyoKKyAqICBmMmZzLmMg LSBGbGFzaC1GcmllbmRseSBGaWxlIFN5c3RlbQorICoKKyAqICBXcml0dGVuIGJ5IEphZWdldWsg S2ltIDxqYWVnZXVrQGtlcm5lbC5vcmc+CisgKgorICogIENvcHlyaWdodCAoQykgMjAxNSAgRnJl ZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCisgKgorICogIEdSVUIgaXMgZnJlZSBzb2Z0d2Fy ZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQorICogIGl0IHVuZGVyIHRo ZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5 CisgKiAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0 aGUgTGljZW5zZSwgb3IKKyAqICAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgor ICoKKyAqICBHUlVCIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1 c2VmdWwsCisgKiAgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGlt cGxpZWQgd2FycmFudHkgb2YKKyAqICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQ QVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vu c2UgZm9yIG1vcmUgZGV0YWlscy4KKyAqCisgKiAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEg Y29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKKyAqICBhbG9uZyB3aXRoIEdS VUIuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uCisgKi8KKyNp bmNsdWRlIDxncnViL2Vyci5oPgorI2luY2x1ZGUgPGdydWIvZmlsZS5oPgorI2luY2x1ZGUgPGdy dWIvbW0uaD4KKyNpbmNsdWRlIDxncnViL21pc2MuaD4KKyNpbmNsdWRlIDxncnViL2Rpc2suaD4K KyNpbmNsdWRlIDxncnViL2RsLmg+CisjaW5jbHVkZSA8Z3J1Yi90eXBlcy5oPgorI2luY2x1ZGUg PGdydWIvY2hhcnNldC5oPgorI2luY2x1ZGUgPGdydWIvZnNoZWxwLmg+CisKK0dSVUJfTU9EX0xJ Q0VOU0UgKCJHUEx2MysiKTsKKworLyogRjJGUyBNYWdpYyBOdW1iZXIgKi8KKyNkZWZpbmUgRjJG U19TVVBFUl9NQUdJQwkweEYyRjUyMDEwCisjZGVmaW5lIENIRUNLU1VNX09GRlNFVAkJNDA5Mgor CisvKiBieXRlLXNpemUgb2Zmc2V0ICovCisjZGVmaW5lIEYyRlNfU1VQRVJfT0ZGU0VUCSgoZ3J1 Yl9kaXNrX2FkZHJfdCkxMDI0KQorI2RlZmluZSBGMkZTX1NVUEVSX09GRlNFVDAJKEYyRlNfU1VQ RVJfT0ZGU0VUID4+IEdSVUJfRElTS19TRUNUT1JfQklUUykKKyNkZWZpbmUgRjJGU19TVVBFUl9P RkZTRVQxCSgoRjJGU19TVVBFUl9PRkZTRVQgKyBGMkZTX0JMS1NJWkUpID4+CVwKKwkJCQkJCUdS VUJfRElTS19TRUNUT1JfQklUUykKKworLyogMTIgYml0cyBmb3IgNDA5NiBieXRlcyAqLworI2Rl ZmluZSBGMkZTX01BWF9MT0dfU0VDVE9SX1NJWkUJMTIKKworLyogOSBiaXRzIGZvciA1MTIgYnl0 ZXMgKi8KKyNkZWZpbmUgRjJGU19NSU5fTE9HX1NFQ1RPUl9TSVpFCTkKKworLyogc3VwcG9ydCBv bmx5IDRLQiBibG9jayAqLworI2RlZmluZSBGMkZTX0JMS19CSVRTCTEyCisjZGVmaW5lIEYyRlNf QkxLU0laRQkoMSA8PCBGMkZTX0JMS19CSVRTKQorI2RlZmluZSBGMkZTX0JMS19TRUNfQklUUwko RjJGU19CTEtfQklUUyAtIEdSVUJfRElTS19TRUNUT1JfQklUUykKKworI2RlZmluZSBWRVJTSU9O X0xFTgkyNTYKKyNkZWZpbmUgRjJGU19NQVhfRVhURU5TSU9OCTY0CisKKyNkZWZpbmUgQ1BfQ09N UEFDVF9TVU1fRkxBRwkweDAwMDAwMDA0CisjZGVmaW5lIENQX1VNT1VOVF9GTEFHCTB4MDAwMDAw MDEKKworI2RlZmluZSBNQVhfQUNUSVZFX0xPR1MJMTYKKyNkZWZpbmUgTUFYX0FDVElWRV9OT0RF X0xPR1MJOAorI2RlZmluZSBNQVhfQUNUSVZFX0RBVEFfTE9HUwk4CisjZGVmaW5lCU5SX0NVUlNF R19EQVRBX1RZUEUJMworI2RlZmluZSBOUl9DVVJTRUdfTk9ERV9UWVBFCTMKKyNkZWZpbmUgTlJf Q1VSU0VHX1RZUEUJKE5SX0NVUlNFR19EQVRBX1RZUEUgKyBOUl9DVVJTRUdfTk9ERV9UWVBFKQor CisjZGVmaW5lIEVOVFJJRVNfSU5fU1VNCTUxMgorI2RlZmluZQlTVU1NQVJZX1NJWkUJNworI2Rl ZmluZQlTVU1fRk9PVEVSX1NJWkUJNQorI2RlZmluZSBKRU5UUllfU0laRQkoc2l6ZW9mKHN0cnVj dCBncnViX2YyZnNfbmF0X2plbnQpKQorI2RlZmluZSBTVU1fRU5UUklFU19TSVpFCShTVU1NQVJZ X1NJWkUgKiBFTlRSSUVTX0lOX1NVTSkKKyNkZWZpbmUgU1VNX0pPVVJOQUxfU0laRQkoRjJGU19C TEtTSVpFIC0gU1VNX0ZPT1RFUl9TSVpFIC1cCisJCQkJU1VNX0VOVFJJRVNfU0laRSkKKyNkZWZp bmUgTkFUX0pPVVJOQUxfRU5UUklFUwkoKFNVTV9KT1VSTkFMX1NJWkUgLSAyKSAvIEpFTlRSWV9T SVpFKQorI2RlZmluZSBOQVRfSk9VUk5BTF9SRVNFUlZFRAkoKFNVTV9KT1VSTkFMX1NJWkUgLSAy KSAlIEpFTlRSWV9TSVpFKQorCisjZGVmaW5lIE5BVF9FTlRSWV9TSVpFIChzaXplb2Yoc3RydWN0 IGdydWJfZjJmc19uYXRfZW50cnkpKQorI2RlZmluZSBOQVRfRU5UUllfUEVSX0JMT0NLIChGMkZT X0JMS1NJWkUgLyBOQVRfRU5UUllfU0laRSkKKworI2RlZmluZSBGMkZTX05BTUVfTEVOCTI1NQor I2RlZmluZSBGMkZTX1NMT1RfTEVOCTgKKyNkZWZpbmUgTlJfREVOVFJZX0lOX0JMT0NLCTIxNAor I2RlZmluZSBTSVpFX09GX0RJUl9FTlRSWQkxMQkvKiBieSBieXRlICovCisjZGVmaW5lIEJJVFNf UEVSX0JZVEUJOAorI2RlZmluZSBTSVpFX09GX0RFTlRSWV9CSVRNQVAJKChOUl9ERU5UUllfSU5f QkxPQ0sgKyBCSVRTX1BFUl9CWVRFIC0gMSkgLyBcCisJCQkJQklUU19QRVJfQllURSkKKyNkZWZp bmUgU0laRV9PRl9SRVNFUlZFRAkoRjJGU19CTEtTSVpFIC0gKChTSVpFX09GX0RJUl9FTlRSWSAr IFwKKwkJCQlGMkZTX1NMT1RfTEVOKSAqIFwKKwkJCQlOUl9ERU5UUllfSU5fQkxPQ0sgKyBTSVpF X09GX0RFTlRSWV9CSVRNQVApKQorCisjZGVmaW5lIEYyRlNfSU5MSU5FX1hBVFRSX0FERFJTCTUw CS8qIDIwMCBieXRlcyBmb3IgaW5saW5lIHhhdHRycyAqLworI2RlZmluZSBERUZfQUREUlNfUEVS X0lOT0RFCTkyMwkvKiBBZGRyZXNzIFBvaW50ZXJzIGluIGFuIElub2RlICovCisKKyNkZWZpbmUg QUREUlNfUEVSX0JMT0NLCTEwMTgJLyogQWRkcmVzcyBQb2ludGVycyBpbiBhIERpcmVjdCBCbG9j ayAqLworI2RlZmluZSBOSURTX1BFUl9CTE9DSwkxMDE4CS8qIE5vZGUgSURzIGluIGFuIEluZGly ZWN0IEJsb2NrICovCisjZGVmaW5lCU5PREVfRElSMV9CTE9DSwkoREVGX0FERFJTX1BFUl9JTk9E RSArIDEpCisjZGVmaW5lCU5PREVfRElSMl9CTE9DSwkoREVGX0FERFJTX1BFUl9JTk9ERSArIDIp CisjZGVmaW5lCU5PREVfSU5EMV9CTE9DSwkoREVGX0FERFJTX1BFUl9JTk9ERSArIDMpCisjZGVm aW5lCU5PREVfSU5EMl9CTE9DSwkoREVGX0FERFJTX1BFUl9JTk9ERSArIDQpCisjZGVmaW5lCU5P REVfRElORF9CTE9DSwkoREVGX0FERFJTX1BFUl9JTk9ERSArIDUpCisKKyNkZWZpbmUgTUFYX0lO TElORV9EQVRBCSg0ICogKERFRl9BRERSU19QRVJfSU5PREUgLSBcCisJCQlGMkZTX0lOTElORV9Y QVRUUl9BRERSUyAtIDEpKQorI2RlZmluZSBOUl9JTkxJTkVfREVOVFJZCShNQVhfSU5MSU5FX0RB VEEgKiBCSVRTX1BFUl9CWVRFIC8gXAorCQkJKChTSVpFX09GX0RJUl9FTlRSWSArIEYyRlNfU0xP VF9MRU4pICogXAorCQkJIEJJVFNfUEVSX0JZVEUgKyAxKSkKKyNkZWZpbmUgSU5MSU5FX0RFTlRS WV9CSVRNQVBfU0laRQkoKE5SX0lOTElORV9ERU5UUlkgKyBcCisJCQlCSVRTX1BFUl9CWVRFIC0g MSkgLyBCSVRTX1BFUl9CWVRFKQorI2RlZmluZSBJTkxJTkVfUkVTRVJWRURfU0laRQkoTUFYX0lO TElORV9EQVRBIC0gXAorCQkJKChTSVpFX09GX0RJUl9FTlRSWSArIEYyRlNfU0xPVF9MRU4pICog XAorCQkJIE5SX0lOTElORV9ERU5UUlkgKyBJTkxJTkVfREVOVFJZX0JJVE1BUF9TSVpFKSkKKyNk ZWZpbmUgQ1VSU0VHX0hPVF9EQVRBCTAKKworI2RlZmluZSBDS1BUX0ZMQUdfU0VUKGNrcHQsIGYp CVwKKwkJKGNrcHQpLT5ja3B0X2ZsYWdzICYgZ3J1Yl9jcHVfdG9fbGUzMl9jb21waWxlX3RpbWUg KGYpCisKKyNkZWZpbmUgRjJGU19JTkxJTkVfWEFUVFIJMHgwMQkvKiBmaWxlIGlubGluZSB4YXR0 ciBmbGFnICovCisjZGVmaW5lIEYyRlNfSU5MSU5FX0RBVEEJMHgwMgkvKiBmaWxlIGlubGluZSBk YXRhIGZsYWcgKi8KKyNkZWZpbmUgRjJGU19JTkxJTkVfREVOVFJZCTB4MDQJLyogZmlsZSBpbmxp bmUgZGVudHJ5IGZsYWcgKi8KKyNkZWZpbmUgRjJGU19EQVRBX0VYSVNUCQkweDA4CS8qIGZpbGUg aW5saW5lIGRhdGEgZXhpc3QgZmxhZyAqLworI2RlZmluZSBGMkZTX0lOTElORV9ET1RTCTB4MTAJ LyogZmlsZSBoYXZpbmcgaW1wbGljaXQgZG90IGRlbnRyaWVzICovCisKK2VudW0gRklMRV9UWVBF Cit7CisgIEYyRlNfRlRfVU5LTk9XTiwKKyAgRjJGU19GVF9SRUdfRklMRSA9IDEsCisgIEYyRlNf RlRfRElSID0gMiwKKyAgRjJGU19GVF9TWU1MSU5LID0gNywKK307CisKK3N0cnVjdCBncnViX2Yy ZnNfc3VwZXJibG9jaworeworICBncnViX3VpbnQzMl90IG1hZ2ljOworICBncnViX3VpbnQxNl90 IGR1bW15MVsyXTsKKyAgZ3J1Yl91aW50MzJfdCBsb2dfc2VjdG9yc2l6ZTsKKyAgZ3J1Yl91aW50 MzJfdCBsb2dfc2VjdG9yc19wZXJfYmxvY2s7CisgIGdydWJfdWludDMyX3QgbG9nX2Jsb2Nrc2l6 ZTsKKyAgZ3J1Yl91aW50MzJfdCBsb2dfYmxvY2tzX3Blcl9zZWc7CisgIGdydWJfdWludDMyX3Qg c2Vnc19wZXJfc2VjOworICBncnViX3VpbnQzMl90IHNlY3NfcGVyX3pvbmU7CisgIGdydWJfdWlu dDMyX3QgY2hlY2tzdW1fb2Zmc2V0OworICBncnViX3VpbnQ4X3QgZHVtbXkyWzQwXTsKKyAgZ3J1 Yl91aW50MzJfdCBjcF9ibGthZGRyOworICBncnViX3VpbnQzMl90IHNpdF9ibGthZGRyOworICBn cnViX3VpbnQzMl90IG5hdF9ibGthZGRyOworICBncnViX3VpbnQzMl90IHNzYV9ibGthZGRyOwor ICBncnViX3VpbnQzMl90IG1haW5fYmxrYWRkcjsKKyAgZ3J1Yl91aW50MzJfdCByb290X2lubzsK KyAgZ3J1Yl91aW50MzJfdCBub2RlX2lubzsKKyAgZ3J1Yl91aW50MzJfdCBtZXRhX2lubzsKKyAg Z3J1Yl91aW50OF90IHV1aWRbMTZdOworICBncnViX3VpbnQxNl90IHZvbHVtZV9uYW1lWzUxMl07 CisgIGdydWJfdWludDMyX3QgZXh0ZW5zaW9uX2NvdW50OworICBncnViX3VpbnQ4X3QgZXh0ZW5z aW9uX2xpc3RbRjJGU19NQVhfRVhURU5TSU9OXVs4XTsKKyAgZ3J1Yl91aW50MzJfdCBjcF9wYXls b2FkOworICBncnViX3VpbnQ4X3QgdmVyc2lvbltWRVJTSU9OX0xFTl07CisgIGdydWJfdWludDhf dCBpbml0X3ZlcnNpb25bVkVSU0lPTl9MRU5dOworfSBHUlVCX1BBQ0tFRDsKKworc3RydWN0IGdy dWJfZjJmc19jaGVja3BvaW50Cit7CisgIGdydWJfdWludDY0X3QgY2hlY2twb2ludF92ZXI7Cisg IGdydWJfdWludDY0X3QgdXNlcl9ibG9ja19jb3VudDsKKyAgZ3J1Yl91aW50NjRfdCB2YWxpZF9i bG9ja19jb3VudDsKKyAgZ3J1Yl91aW50MzJfdCByc3ZkX3NlZ21lbnRfY291bnQ7CisgIGdydWJf dWludDMyX3Qgb3ZlcnByb3Zfc2VnbWVudF9jb3VudDsKKyAgZ3J1Yl91aW50MzJfdCBmcmVlX3Nl Z21lbnRfY291bnQ7CisgIGdydWJfdWludDMyX3QgY3VyX25vZGVfc2Vnbm9bTUFYX0FDVElWRV9O T0RFX0xPR1NdOworICBncnViX3VpbnQxNl90IGN1cl9ub2RlX2Jsa29mZltNQVhfQUNUSVZFX05P REVfTE9HU107CisgIGdydWJfdWludDMyX3QgY3VyX2RhdGFfc2Vnbm9bTUFYX0FDVElWRV9EQVRB X0xPR1NdOworICBncnViX3VpbnQxNl90IGN1cl9kYXRhX2Jsa29mZltNQVhfQUNUSVZFX0RBVEFf TE9HU107CisgIGdydWJfdWludDMyX3QgY2twdF9mbGFnczsKKyAgZ3J1Yl91aW50MzJfdCBjcF9w YWNrX3RvdGFsX2Jsb2NrX2NvdW50OworICBncnViX3VpbnQzMl90IGNwX3BhY2tfc3RhcnRfc3Vt OworICBncnViX3VpbnQzMl90IHZhbGlkX25vZGVfY291bnQ7CisgIGdydWJfdWludDMyX3QgdmFs aWRfaW5vZGVfY291bnQ7CisgIGdydWJfdWludDMyX3QgbmV4dF9mcmVlX25pZDsKKyAgZ3J1Yl91 aW50MzJfdCBzaXRfdmVyX2JpdG1hcF9ieXRlc2l6ZTsKKyAgZ3J1Yl91aW50MzJfdCBuYXRfdmVy X2JpdG1hcF9ieXRlc2l6ZTsKKyAgZ3J1Yl91aW50MzJfdCBjaGVja3N1bV9vZmZzZXQ7CisgIGdy dWJfdWludDY0X3QgZWxhcHNlZF90aW1lOworICBncnViX3VpbnQ4X3QgYWxsb2NfdHlwZVtNQVhf QUNUSVZFX0xPR1NdOworICBncnViX3VpbnQ4X3Qgc2l0X25hdF92ZXJzaW9uX2JpdG1hcFszOTAw XTsKKyAgZ3J1Yl91aW50MzJfdCBjaGVja3N1bTsKK30gR1JVQl9QQUNLRUQ7CisKK3N0cnVjdCBn cnViX2YyZnNfbmF0X2VudHJ5IHsKKyAgZ3J1Yl91aW50OF90IHZlcnNpb247CisgIGdydWJfdWlu dDMyX3QgaW5vOworICBncnViX3VpbnQzMl90IGJsb2NrX2FkZHI7Cit9IEdSVUJfUEFDS0VEOwor CitzdHJ1Y3QgZ3J1Yl9mMmZzX25hdF9qZW50Cit7CisgIGdydWJfdWludDMyX3QgbmlkOworICBz dHJ1Y3QgZ3J1Yl9mMmZzX25hdF9lbnRyeSBuZTsKK30gR1JVQl9QQUNLRUQ7CisKK3N0cnVjdCBn cnViX2YyZnNfbmF0X2pvdXJuYWwgeworICBncnViX3VpbnQxNl90IG5fbmF0czsKKyAgc3RydWN0 IGdydWJfZjJmc19uYXRfamVudCBlbnRyaWVzW05BVF9KT1VSTkFMX0VOVFJJRVNdOworICBncnVi X3VpbnQ4X3QgcmVzZXJ2ZWRbTkFUX0pPVVJOQUxfUkVTRVJWRURdOworfSBHUlVCX1BBQ0tFRDsK Kworc3RydWN0IGdydWJfZjJmc19uYXRfYmxvY2sgeworICBzdHJ1Y3QgZ3J1Yl9mMmZzX25hdF9l bnRyeSBuZVtOQVRfRU5UUllfUEVSX0JMT0NLXTsKK30gR1JVQl9QQUNLRUQ7CisKK3N0cnVjdCBn cnViX2YyZnNfZGlyX2VudHJ5Cit7CisgIGdydWJfdWludDMyX3QgaGFzaF9jb2RlOworICBncnVi X3VpbnQzMl90IGlubzsKKyAgZ3J1Yl91aW50MTZfdCBuYW1lX2xlbjsKKyAgZ3J1Yl91aW50OF90 IGZpbGVfdHlwZTsKK30gR1JVQl9QQUNLRUQ7CisKK3N0cnVjdCBncnViX2YyZnNfaW5saW5lX2Rl bnRyeQoreworICBncnViX3VpbnQ4X3QgZGVudHJ5X2JpdG1hcFtJTkxJTkVfREVOVFJZX0JJVE1B UF9TSVpFXTsKKyAgZ3J1Yl91aW50OF90IHJlc2VydmVkW0lOTElORV9SRVNFUlZFRF9TSVpFXTsK KyAgc3RydWN0IGdydWJfZjJmc19kaXJfZW50cnkgZGVudHJ5W05SX0lOTElORV9ERU5UUlldOwor ICBncnViX3VpbnQ4X3QgZmlsZW5hbWVbTlJfSU5MSU5FX0RFTlRSWV1bRjJGU19TTE9UX0xFTl07 Cit9IEdSVUJfUEFDS0VEOworCitzdHJ1Y3QgZ3J1Yl9mMmZzX2RlbnRyeV9ibG9jayB7CisgIGdy dWJfdWludDhfdCBkZW50cnlfYml0bWFwW1NJWkVfT0ZfREVOVFJZX0JJVE1BUF07CisgIGdydWJf dWludDhfdCByZXNlcnZlZFtTSVpFX09GX1JFU0VSVkVEXTsKKyAgc3RydWN0IGdydWJfZjJmc19k aXJfZW50cnkgZGVudHJ5W05SX0RFTlRSWV9JTl9CTE9DS107CisgIGdydWJfdWludDhfdCBmaWxl bmFtZVtOUl9ERU5UUllfSU5fQkxPQ0tdW0YyRlNfU0xPVF9MRU5dOworfSBHUlVCX1BBQ0tFRDsK Kworc3RydWN0IGdydWJfZjJmc19pbm9kZQoreworICBncnViX3VpbnQxNl90IGlfbW9kZTsKKyAg Z3J1Yl91aW50OF90IGlfYWR2aXNlOworICBncnViX3VpbnQ4X3QgaV9pbmxpbmU7CisgIGdydWJf dWludDMyX3QgaV91aWQ7CisgIGdydWJfdWludDMyX3QgaV9naWQ7CisgIGdydWJfdWludDMyX3Qg aV9saW5rczsKKyAgZ3J1Yl91aW50NjRfdCBpX3NpemU7CisgIGdydWJfdWludDY0X3QgaV9ibG9j a3M7CisgIGdydWJfdWludDY0X3QgaV9hdGltZTsKKyAgZ3J1Yl91aW50NjRfdCBpX2N0aW1lOwor ICBncnViX3VpbnQ2NF90IGlfbXRpbWU7CisgIGdydWJfdWludDMyX3QgaV9hdGltZV9uc2VjOwor ICBncnViX3VpbnQzMl90IGlfY3RpbWVfbnNlYzsKKyAgZ3J1Yl91aW50MzJfdCBpX210aW1lX25z ZWM7CisgIGdydWJfdWludDMyX3QgaV9nZW5lcmF0aW9uOworICBncnViX3VpbnQzMl90IGlfY3Vy cmVudF9kZXB0aDsKKyAgZ3J1Yl91aW50MzJfdCBpX3hhdHRyX25pZDsKKyAgZ3J1Yl91aW50MzJf dCBpX2ZsYWdzOworICBncnViX3VpbnQzMl90IGlfcGlubzsKKyAgZ3J1Yl91aW50MzJfdCBpX25h bWVsZW47CisgIGdydWJfdWludDhfdCBpX25hbWVbRjJGU19OQU1FX0xFTl07CisgIGdydWJfdWlu dDhfdCBpX2Rpcl9sZXZlbDsKKyAgZ3J1Yl91aW50OF90IGlfZXh0WzEyXTsKKyAgZ3J1Yl91aW50 MzJfdCBpX2FkZHJbREVGX0FERFJTX1BFUl9JTk9ERV07CisgIGdydWJfdWludDMyX3QgaV9uaWRb NV07Cit9IEdSVUJfUEFDS0VEOworCitzdHJ1Y3QgZ3J1Yl9kaXJlY3Rfbm9kZSB7CisgIGdydWJf dWludDMyX3QgYWRkcltBRERSU19QRVJfQkxPQ0tdOworfSBHUlVCX1BBQ0tFRDsKKworc3RydWN0 IGdydWJfaW5kaXJlY3Rfbm9kZSB7CisgIGdydWJfdWludDMyX3QgbmlkW05JRFNfUEVSX0JMT0NL XTsKK30gR1JVQl9QQUNLRUQ7CisKK3N0cnVjdCBncnViX2YyZnNfbm9kZQoreworICB1bmlvbgor ICB7CisgICAgc3RydWN0IGdydWJfZjJmc19pbm9kZSBpOworICAgIHN0cnVjdCBncnViX2RpcmVj dF9ub2RlIGRuOworICAgIHN0cnVjdCBncnViX2luZGlyZWN0X25vZGUgaW47CisgICAgY2hhciBi dWZbRjJGU19CTEtTSVpFIC0gNDBdOwkvKiBTaG91bGQgb2NjdXB5IEYyRlNfQkxLU0laRSB0b3Rh bGx5ICovCisgIH07CisgIGdydWJfdWludDhfdCBkdW1teVs0MF07Cit9IEdSVUJfUEFDS0VEOwor CitzdHJ1Y3QgZ3J1Yl9mc2hlbHBfbm9kZQoreworICBzdHJ1Y3QgZ3J1Yl9mMmZzX2RhdGEgKmRh dGE7CisgIHN0cnVjdCBncnViX2YyZnNfbm9kZSBpbm9kZTsKKyAgZ3J1Yl91aW50MzJfdCBpbm87 CisgIGludCBpbm9kZV9yZWFkOworfTsKKworc3RydWN0IGdydWJfZjJmc19kYXRhCit7CisgIHN0 cnVjdCBncnViX2YyZnNfc3VwZXJibG9jayBzYmxvY2s7CisgIHN0cnVjdCBncnViX2YyZnNfY2hl Y2twb2ludCBja3B0OworCisgIGdydWJfdWludDMyX3Qgcm9vdF9pbm87CisgIGdydWJfdWludDMy X3QgYmxvY2tzX3Blcl9zZWc7CisgIGdydWJfdWludDMyX3QgY3BfYmxrYWRkcjsKKyAgZ3J1Yl91 aW50MzJfdCBuYXRfYmxrYWRkcjsKKworICBzdHJ1Y3QgZ3J1Yl9mMmZzX25hdF9qb3VybmFsIG5h dF9qOworICBjaGFyICpuYXRfYml0bWFwOworCisgIGdydWJfZGlza190IGRpc2s7CisgIHN0cnVj dCBncnViX2YyZnNfbm9kZSAqaW5vZGU7CisgIHN0cnVjdCBncnViX2ZzaGVscF9ub2RlIGRpcm9w ZW47Cit9OworCitzdHJ1Y3QgZ3J1Yl9mMmZzX2Rpcl9pdGVyX2N0eAoreworICBzdHJ1Y3QgZ3J1 Yl9mMmZzX2RhdGEgKmRhdGE7CisgIGdydWJfZnNoZWxwX2l0ZXJhdGVfZGlyX2hvb2tfdCBob29r OworICB2b2lkICpob29rX2RhdGE7CisgIGdydWJfdWludDMyX3QgKmJpdG1hcDsKKyAgZ3J1Yl91 aW50OF90ICgqZmlsZW5hbWUpW0YyRlNfU0xPVF9MRU5dOworICBzdHJ1Y3QgZ3J1Yl9mMmZzX2Rp cl9lbnRyeSAqZGVudHJ5OworICBpbnQgbWF4OworfTsKKworc3RydWN0IGdydWJfZjJmc19kaXJf Y3R4Cit7CisgIGdydWJfZnNfZGlyX2hvb2tfdCBob29rOworICB2b2lkICpob29rX2RhdGE7Cisg IHN0cnVjdCBncnViX2YyZnNfZGF0YSAqZGF0YTsKK307CisKK3N0YXRpYyBncnViX2RsX3QgbXlf bW9kOworCitzdGF0aWMgaW5saW5lIGludAorZ3J1Yl9nZW5lcmljX3Rlc3RfYml0IChpbnQgbnIs IGNvbnN0IGdydWJfdWludDMyX3QgKmFkZHIpCit7CisgIHJldHVybiAxVUwgJiAoYWRkcltuciAv IDMyXSA+PiAobnIgJiAzMSkpOworfQorCitzdGF0aWMgaW5saW5lIGNoYXIgKgorX19pbmxpbmVf YWRkciAoc3RydWN0IGdydWJfZjJmc19pbm9kZSAqaW5vZGUpCit7CisgIHJldHVybiAoY2hhciAq KSZpbm9kZS0+aV9hZGRyWzFdOworfQorCitzdGF0aWMgaW5saW5lIGdydWJfdWludDY0X3QKK2dy dWJfZjJmc19maWxlX3NpemUgKHN0cnVjdCBncnViX2YyZnNfaW5vZGUgKmlub2RlKQoreworICBy ZXR1cm4gZ3J1Yl9sZV90b19jcHU2NCAoaW5vZGUtPmlfc2l6ZSk7Cit9CisKK3N0YXRpYyBpbmxp bmUgZ3J1Yl91aW50MzJfdAorX19zdGFydF9jcF9hZGRyIChzdHJ1Y3QgZ3J1Yl9mMmZzX2RhdGEg KmRhdGEpCit7CisgIHN0cnVjdCBncnViX2YyZnNfY2hlY2twb2ludCAqY2twdCA9ICZkYXRhLT5j a3B0OworICBncnViX3VpbnQ2NF90IGNrcHRfdmVyc2lvbiA9IGdydWJfbGVfdG9fY3B1NjQgKGNr cHQtPmNoZWNrcG9pbnRfdmVyKTsKKyAgZ3J1Yl91aW50MzJfdCBzdGFydF9hZGRyID0gZGF0YS0+ Y3BfYmxrYWRkcjsKKworICBpZiAoIShja3B0X3ZlcnNpb24gJiAxKSkKKyAgICByZXR1cm4gc3Rh cnRfYWRkciArIGRhdGEtPmJsb2Nrc19wZXJfc2VnOworICByZXR1cm4gc3RhcnRfYWRkcjsKK30K Kworc3RhdGljIGlubGluZSBncnViX3VpbnQzMl90CitfX3N0YXJ0X3N1bV9ibG9jayAoc3RydWN0 IGdydWJfZjJmc19kYXRhICpkYXRhKQoreworICBzdHJ1Y3QgZ3J1Yl9mMmZzX2NoZWNrcG9pbnQg KmNrcHQgPSAmZGF0YS0+Y2twdDsKKworICByZXR1cm4gX19zdGFydF9jcF9hZGRyIChkYXRhKSAr IGdydWJfbGVfdG9fY3B1MzIgKGNrcHQtPmNwX3BhY2tfc3RhcnRfc3VtKTsKK30KKworc3RhdGlj IGlubGluZSBncnViX3VpbnQzMl90CitfX3N1bV9ibGtfYWRkciAoc3RydWN0IGdydWJfZjJmc19k YXRhICpkYXRhLCBpbnQgYmFzZSwgaW50IHR5cGUpCit7CisgIHN0cnVjdCBncnViX2YyZnNfY2hl Y2twb2ludCAqY2twdCA9ICZkYXRhLT5ja3B0OworCisgIHJldHVybiBfX3N0YXJ0X2NwX2FkZHIg KGRhdGEpICsKKwlncnViX2xlX3RvX2NwdTMyIChja3B0LT5jcF9wYWNrX3RvdGFsX2Jsb2NrX2Nv dW50KQorCS0gKGJhc2UgKyAxKSArIHR5cGU7Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZCAqCitf X25hdF9iaXRtYXBfcHRyIChzdHJ1Y3QgZ3J1Yl9mMmZzX2RhdGEgKmRhdGEpCit7CisgIHN0cnVj dCBncnViX2YyZnNfY2hlY2twb2ludCAqY2twdCA9ICZkYXRhLT5ja3B0OworICBncnViX3VpbnQz Ml90IG9mZnNldDsKKworICBpZiAoZ3J1Yl9sZV90b19jcHUzMiAoZGF0YS0+c2Jsb2NrLmNwX3Bh eWxvYWQpID4gMCkKKyAgICByZXR1cm4gY2twdC0+c2l0X25hdF92ZXJzaW9uX2JpdG1hcDsKKwor ICBvZmZzZXQgPSBncnViX2xlX3RvX2NwdTMyIChja3B0LT5zaXRfdmVyX2JpdG1hcF9ieXRlc2l6 ZSk7CisgIHJldHVybiBja3B0LT5zaXRfbmF0X3ZlcnNpb25fYml0bWFwICsgb2Zmc2V0OworfQor CitzdGF0aWMgaW5saW5lIGdydWJfdWludDMyX3QKK19fZ2V0X25vZGVfaWQgKHN0cnVjdCBncnVi X2YyZnNfbm9kZSAqcm4sIGludCBvZmYsIGludCBpbm9kZV9ibG9jaykKK3sKKyAgaWYgKGlub2Rl X2Jsb2NrKQorICAgIHJldHVybiBncnViX2xlX3RvX2NwdTMyIChybi0+aS5pX25pZFtvZmYgLSBO T0RFX0RJUjFfQkxPQ0tdKTsKKyAgcmV0dXJuIGdydWJfbGVfdG9fY3B1MzIgKHJuLT5pbi5uaWRb b2ZmXSk7Cit9CisKK3N0YXRpYyBpbmxpbmUgZ3J1Yl9lcnJfdAorZ3J1Yl9mMmZzX2Jsb2NrX3Jl YWQgKHN0cnVjdCBncnViX2YyZnNfZGF0YSAqZGF0YSwgZ3J1Yl91aW50MzJfdCBibGthZGRyLCB2 b2lkICpidWYpCit7CisgIHJldHVybiBncnViX2Rpc2tfcmVhZCAoZGF0YS0+ZGlzaywKKwkJKChn cnViX2Rpc2tfYWRkcl90KWJsa2FkZHIpIDw8IEYyRlNfQkxLX1NFQ19CSVRTLAorCQkwLCBGMkZT X0JMS1NJWkUsIGJ1Zik7Cit9CisKKy8qCisgKiBDUkMzMgorKi8KKyNkZWZpbmUgQ1JDUE9MWV9M RSAweGVkYjg4MzIwCisKK3N0YXRpYyBpbmxpbmUgZ3J1Yl91aW50MzJfdAorZ3J1Yl9mMmZzX2Nh bF9jcmMzMiAoY29uc3Qgdm9pZCAqYnVmLCBjb25zdCBncnViX3VpbnQzMl90IGxlbikKK3sKKyAg Z3J1Yl91aW50MzJfdCBjcmMgPSBGMkZTX1NVUEVSX01BR0lDOworICB1bnNpZ25lZCBjaGFyICpw ID0gKHVuc2lnbmVkIGNoYXIgKilidWY7CisgIGdydWJfdWludDMyX3QgdG1wID0gbGVuOworICBp bnQgaTsKKworICB3aGlsZSAodG1wLS0pCisgICAgeworICAgICAgY3JjIF49ICpwKys7CisgICAg ICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKQorICAgICAgICBjcmMgPSAoY3JjID4+IDEpIF4gKChj cmMgJiAxKSA/IENSQ1BPTFlfTEUgOiAwKTsKKyAgICB9CisgIHJldHVybiBjcmM7Cit9CisKK3N0 YXRpYyBpbmxpbmUgaW50CitncnViX2YyZnNfY3JjX3ZhbGlkIChncnViX3VpbnQzMl90IGJsa19j cmMsIHZvaWQgKmJ1ZiwgY29uc3QgZ3J1Yl91aW50MzJfdCBsZW4pCit7CisgIGdydWJfdWludDMy X3QgY2FsX2NyYyA9IDA7CisKKyAgY2FsX2NyYyA9IGdydWJfZjJmc19jYWxfY3JjMzIgKGJ1Ziwg bGVuKTsKKworICByZXR1cm4gKGNhbF9jcmMgPT0gYmxrX2NyYykgPyAxIDogMDsKK30KKworc3Rh dGljIGlubGluZSBpbnQKK2dydWJfZjJmc190ZXN0X2JpdCAoZ3J1Yl91aW50MzJfdCBuciwgY29u c3QgY2hhciAqcCkKK3sKKyAgaW50IG1hc2s7CisKKyAgcCArPSAobnIgPj4gMyk7CisgIG1hc2sg PSAxIDw8ICg3IC0gKG5yICYgMHgwNykpOworICByZXR1cm4gKG1hc2sgJiAqcCkgIT0gMDsKK30K Kworc3RhdGljIGludAorZ3J1Yl9mMmZzX3Nhbml0eV9jaGVja19zYiAoc3RydWN0IGdydWJfZjJm c19zdXBlcmJsb2NrICpzYikKK3sKKyAgZ3J1Yl91aW50MzJfdCBsb2dfc2VjdG9yc2l6ZSwgbG9n X3NlY3RvcnNfcGVyX2Jsb2NrOworCisgIGlmIChzYi0+bWFnaWMgIT0gZ3J1Yl9jcHVfdG9fbGUz Ml9jb21waWxlX3RpbWUgKEYyRlNfU1VQRVJfTUFHSUMpKQorICAgIHJldHVybiAtMTsKKworICBp ZiAoc2ItPmxvZ19ibG9ja3NpemUgIT0gZ3J1Yl9jcHVfdG9fbGUzMl9jb21waWxlX3RpbWUgKEYy RlNfQkxLX0JJVFMpKQorICAgIHJldHVybiAtMTsKKworICBsb2dfc2VjdG9yc2l6ZSA9IGdydWJf bGVfdG9fY3B1MzIgKHNiLT5sb2dfc2VjdG9yc2l6ZSk7CisgIGxvZ19zZWN0b3JzX3Blcl9ibG9j ayA9IGdydWJfbGVfdG9fY3B1MzIgKHNiLT5sb2dfc2VjdG9yc19wZXJfYmxvY2spOworCisgIGlm IChsb2dfc2VjdG9yc2l6ZSA+IEYyRlNfTUFYX0xPR19TRUNUT1JfU0laRSkKKyAgICByZXR1cm4g LTE7CisKKyAgaWYgKGxvZ19zZWN0b3JzaXplIDwgRjJGU19NSU5fTE9HX1NFQ1RPUl9TSVpFKQor ICAgIHJldHVybiAtMTsKKworICBpZiAobG9nX3NlY3RvcnNfcGVyX2Jsb2NrICsgbG9nX3NlY3Rv cnNpemUgIT0gRjJGU19NQVhfTE9HX1NFQ1RPUl9TSVpFKQorICAgIHJldHVybiAtMTsKKworICBy ZXR1cm4gMDsKK30KKworc3RhdGljIGludAorZ3J1Yl9mMmZzX3JlYWRfc2IgKHN0cnVjdCBncnVi X2YyZnNfZGF0YSAqZGF0YSwgZ3J1Yl9kaXNrX2FkZHJfdCBvZmZzZXQpCit7CisgIGdydWJfZGlz a190IGRpc2sgPSBkYXRhLT5kaXNrOworICBncnViX2Vycl90IGVycjsKKworICAvKiBSZWFkIGZp cnN0IHN1cGVyIGJsb2NrLiAqLworICBlcnIgPSBncnViX2Rpc2tfcmVhZCAoZGlzaywgb2Zmc2V0 LCAwLCBzaXplb2YgKGRhdGEtPnNibG9jayksICZkYXRhLT5zYmxvY2spOworICBpZiAoZXJyKQor ICAgIHJldHVybiAtMTsKKworICByZXR1cm4gZ3J1Yl9mMmZzX3Nhbml0eV9jaGVja19zYiAoJmRh dGEtPnNibG9jayk7Cit9CisKK3N0YXRpYyB2b2lkICoKK3ZhbGlkYXRlX2NoZWNrcG9pbnQgKHN0 cnVjdCBncnViX2YyZnNfZGF0YSAqZGF0YSwgZ3J1Yl91aW50MzJfdCBjcF9hZGRyLAorCWdydWJf dWludDY0X3QgKnZlcnNpb24pCit7CisgIHZvaWQgKmNwX3BhZ2VfMSwgKmNwX3BhZ2VfMjsKKyAg c3RydWN0IGdydWJfZjJmc19jaGVja3BvaW50ICpjcF9ibG9jazsKKyAgZ3J1Yl91aW50NjRfdCBj dXJfdmVyc2lvbiA9IDAsIHByZV92ZXJzaW9uID0gMDsKKyAgZ3J1Yl91aW50MzJfdCBjcmMgPSAw OworICBncnViX3VpbnQzMl90IGNyY19vZmZzZXQ7CisgIGdydWJfZXJyX3QgZXJyOworCisgIC8q IFJlYWQgdGhlIDFzdCBjcCBibG9jayBpbiB0aGlzIENQIHBhY2sgKi8KKyAgY3BfcGFnZV8xID0g Z3J1Yl9tYWxsb2MgKEYyRlNfQkxLU0laRSk7CisgIGlmICghY3BfcGFnZV8xKQorICAgIHJldHVy biBOVUxMOworCisgIGVyciA9IGdydWJfZjJmc19ibG9ja19yZWFkIChkYXRhLCBjcF9hZGRyLCBj cF9wYWdlXzEpOworICBpZiAoZXJyKQorICAgIGdvdG8gaW52YWxpZF9jcDE7CisKKyAgY3BfYmxv Y2sgPSAoc3RydWN0IGdydWJfZjJmc19jaGVja3BvaW50ICopY3BfcGFnZV8xOworICBjcmNfb2Zm c2V0ID0gZ3J1Yl9sZV90b19jcHUzMiAoY3BfYmxvY2stPmNoZWNrc3VtX29mZnNldCk7CisgIGlm IChjcmNfb2Zmc2V0ICE9IENIRUNLU1VNX09GRlNFVCkKKyAgICBnb3RvIGludmFsaWRfY3AxOwor CisgIGNyYyA9IGdydWJfbGVfdG9fY3B1MzIgKCooZ3J1Yl91aW50MzJfdCAqKSgoY2hhciAqKWNw X2Jsb2NrICsgY3JjX29mZnNldCkpOworICBpZiAoIWdydWJfZjJmc19jcmNfdmFsaWQgKGNyYywg Y3BfYmxvY2ssIGNyY19vZmZzZXQpKQorICAgIGdvdG8gaW52YWxpZF9jcDE7CisKKyAgcHJlX3Zl cnNpb24gPSBncnViX2xlX3RvX2NwdTY0IChjcF9ibG9jay0+Y2hlY2twb2ludF92ZXIpOworCisg IC8qIFJlYWQgdGhlIDJuZCBjcCBibG9jayBpbiB0aGlzIENQIHBhY2sgKi8KKyAgY3BfcGFnZV8y ID0gZ3J1Yl9tYWxsb2MgKEYyRlNfQkxLU0laRSk7CisgIGlmICghY3BfcGFnZV8yKQorICAgIGdv dG8gaW52YWxpZF9jcDE7CisKKyAgY3BfYWRkciArPSBncnViX2xlX3RvX2NwdTMyIChjcF9ibG9j ay0+Y3BfcGFja190b3RhbF9ibG9ja19jb3VudCkgLSAxOworCisgIGVyciA9IGdydWJfZjJmc19i bG9ja19yZWFkIChkYXRhLCBjcF9hZGRyLCBjcF9wYWdlXzIpOworICBpZiAoZXJyKQorICAgIGdv dG8gaW52YWxpZF9jcDI7CisKKyAgY3BfYmxvY2sgPSAoc3RydWN0IGdydWJfZjJmc19jaGVja3Bv aW50ICopY3BfcGFnZV8yOworICBjcmNfb2Zmc2V0ID0gZ3J1Yl9sZV90b19jcHUzMiAoY3BfYmxv Y2stPmNoZWNrc3VtX29mZnNldCk7CisgIGlmIChjcmNfb2Zmc2V0ICE9IENIRUNLU1VNX09GRlNF VCkKKyAgICBnb3RvIGludmFsaWRfY3AyOworCisgIGNyYyA9IGdydWJfbGVfdG9fY3B1MzIgKCoo Z3J1Yl91aW50MzJfdCAqKSgoY2hhciAqKWNwX2Jsb2NrICsgY3JjX29mZnNldCkpOworICBpZiAo IWdydWJfZjJmc19jcmNfdmFsaWQgKGNyYywgY3BfYmxvY2ssIGNyY19vZmZzZXQpKQorICAgIGdv dG8gaW52YWxpZF9jcDI7CisKKyAgY3VyX3ZlcnNpb24gPSBncnViX2xlX3RvX2NwdTY0IChjcF9i bG9jay0+Y2hlY2twb2ludF92ZXIpOworICBpZiAoY3VyX3ZlcnNpb24gPT0gcHJlX3ZlcnNpb24p CisgICAgeworICAgICAgKnZlcnNpb24gPSBjdXJfdmVyc2lvbjsKKyAgICAgIGdydWJfZnJlZSAo Y3BfcGFnZV8yKTsKKyAgICAgIHJldHVybiBjcF9wYWdlXzE7CisgICAgfQorCitpbnZhbGlkX2Nw MjoKKyAgZ3J1Yl9mcmVlIChjcF9wYWdlXzIpOworaW52YWxpZF9jcDE6CisgIGdydWJfZnJlZSAo Y3BfcGFnZV8xKTsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBncnViX2Vycl90CitncnVi X2YyZnNfcmVhZF9jcCAoc3RydWN0IGdydWJfZjJmc19kYXRhICpkYXRhKQoreworICB2b2lkICpj cDEsICpjcDIsICpjdXJfcGFnZTsKKyAgZ3J1Yl91aW50NjRfdCBjcDFfdmVyc2lvbiA9IDAsIGNw Ml92ZXJzaW9uID0gMDsKKyAgZ3J1Yl91aW50NjRfdCBjcF9zdGFydF9ibGtfbm87CisKKyAgLyoK KyAgICogRmluZGluZyBvdXQgdmFsaWQgY3AgYmxvY2sgaW52b2x2ZXMgcmVhZCBib3RoCisgICAq IHNldHMgKGNwIHBhY2sxIGFuZCBjcCBwYWNrIDIpCisgICAqLworICBjcF9zdGFydF9ibGtfbm8g PSBkYXRhLT5jcF9ibGthZGRyOworICBjcDEgPSB2YWxpZGF0ZV9jaGVja3BvaW50IChkYXRhLCBj cF9zdGFydF9ibGtfbm8sICZjcDFfdmVyc2lvbik7CisgIGlmICghY3AxICYmIGdydWJfZXJybm8p CisgICAgcmV0dXJuIGdydWJfZXJybm87CisKKyAgLyogVGhlIHNlY29uZCBjaGVja3BvaW50IHBh Y2sgc2hvdWxkIHN0YXJ0IGF0IHRoZSBuZXh0IHNlZ21lbnQgKi8KKyAgY3Bfc3RhcnRfYmxrX25v ICs9IGRhdGEtPmJsb2Nrc19wZXJfc2VnOworICBjcDIgPSB2YWxpZGF0ZV9jaGVja3BvaW50IChk YXRhLCBjcF9zdGFydF9ibGtfbm8sICZjcDJfdmVyc2lvbik7CisgIGlmICghY3AyICYmIGdydWJf ZXJybm8pCisgICAgeworICAgICAgZ3J1Yl9mcmVlIChjcDEpOworICAgICAgcmV0dXJuIGdydWJf ZXJybm87CisgICAgfQorCisgIGlmIChjcDEgJiYgY3AyKQorICAgIGN1cl9wYWdlID0gKGNwMl92 ZXJzaW9uID4gY3AxX3ZlcnNpb24pID8gY3AyIDogY3AxOworICBlbHNlIGlmIChjcDEpCisgICAg Y3VyX3BhZ2UgPSBjcDE7CisgIGVsc2UgaWYgKGNwMikKKyAgICBjdXJfcGFnZSA9IGNwMjsKKyAg ZWxzZQorICAgIHJldHVybiBncnViX2Vycm9yIChHUlVCX0VSUl9CQURfRlMsICJubyBjaGVja3Bv aW50cyIpOworCisgIGdydWJfbWVtY3B5ICgmZGF0YS0+Y2twdCwgY3VyX3BhZ2UsIEYyRlNfQkxL U0laRSk7CisKKyAgZ3J1Yl9mcmVlIChjcDEpOworICBncnViX2ZyZWUgKGNwMik7CisgIHJldHVy biAwOworfQorCitzdGF0aWMgZ3J1Yl9lcnJfdAorZ2V0X25hdF9qb3VybmFsIChzdHJ1Y3QgZ3J1 Yl9mMmZzX2RhdGEgKmRhdGEpCit7CisgIGdydWJfdWludDMyX3QgYmxvY2s7CisgIGNoYXIgKmJ1 ZjsKKyAgZ3J1Yl9lcnJfdCBlcnI7CisKKyAgYnVmID0gZ3J1Yl9tYWxsb2MgKEYyRlNfQkxLU0la RSk7CisgIGlmICghYnVmKQorICAgIHJldHVybiBncnViX2Vycm5vOworCisgIGlmIChDS1BUX0ZM QUdfU0VUKCZkYXRhLT5ja3B0LCBDUF9DT01QQUNUX1NVTV9GTEFHKSkKKyAgICBibG9jayA9IF9f c3RhcnRfc3VtX2Jsb2NrIChkYXRhKTsKKyAgZWxzZSBpZiAoQ0tQVF9GTEFHX1NFVCAoJmRhdGEt PmNrcHQsIENQX1VNT1VOVF9GTEFHKSkKKyAgICBibG9jayA9IF9fc3VtX2Jsa19hZGRyIChkYXRh LCBOUl9DVVJTRUdfVFlQRSwgQ1VSU0VHX0hPVF9EQVRBKTsKKyAgZWxzZQorICAgIGJsb2NrID0g X19zdW1fYmxrX2FkZHIgKGRhdGEsIE5SX0NVUlNFR19EQVRBX1RZUEUsIENVUlNFR19IT1RfREFU QSk7CisKKyAgZXJyID0gZ3J1Yl9mMmZzX2Jsb2NrX3JlYWQgKGRhdGEsIGJsb2NrLCBidWYpOwor ICBpZiAoZXJyKQorICAgIGdvdG8gZmFpbDsKKworICBpZiAoQ0tQVF9GTEFHX1NFVCAoJmRhdGEt PmNrcHQsIENQX0NPTVBBQ1RfU1VNX0ZMQUcpKQorICAgIGdydWJfbWVtY3B5ICgmZGF0YS0+bmF0 X2osIGJ1ZiwgU1VNX0pPVVJOQUxfU0laRSk7CisgIGVsc2UKKyAgICBncnViX21lbWNweSAoJmRh dGEtPm5hdF9qLCBidWYgKyBTVU1fRU5UUklFU19TSVpFLCBTVU1fSk9VUk5BTF9TSVpFKTsKKwor ZmFpbDoKKyAgZ3J1Yl9mcmVlIChidWYpOworICByZXR1cm4gZXJyOworfQorCitzdGF0aWMgZ3J1 Yl91aW50MzJfdAorZ2V0X2Jsa2FkZHJfZnJvbV9uYXRfam91cm5hbCAoc3RydWN0IGdydWJfZjJm c19kYXRhICpkYXRhLCBncnViX3VpbnQzMl90IG5pZCkKK3sKKyAgZ3J1Yl91aW50MTZfdCBuID0g Z3J1Yl9sZV90b19jcHUxNiAoZGF0YS0+bmF0X2oubl9uYXRzKTsKKyAgZ3J1Yl91aW50MzJfdCBi bGthZGRyID0gMDsKKyAgZ3J1Yl91aW50MTZfdCBpOworCisgIGZvciAoaSA9IDA7IGkgPCBuOyBp KyspCisgICAgeworICAgICAgaWYgKGdydWJfbGVfdG9fY3B1MzIgKGRhdGEtPm5hdF9qLmVudHJp ZXNbaV0ubmlkKSA9PSBuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBibGthZGRyID0gZ3J1Yl9s ZV90b19jcHUzMiAoZGF0YS0+bmF0X2ouZW50cmllc1tpXS5uZS5ibG9ja19hZGRyKTsKKyAgICAg ICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKyAgcmV0dXJuIGJsa2FkZHI7Cit9CisKK3N0 YXRpYyBncnViX3VpbnQzMl90CitnZXRfbm9kZV9ibGthZGRyIChzdHJ1Y3QgZ3J1Yl9mMmZzX2Rh dGEgKmRhdGEsIGdydWJfdWludDMyX3QgbmlkKQoreworICBzdHJ1Y3QgZ3J1Yl9mMmZzX25hdF9i bG9jayAqbmF0X2Jsb2NrOworICBncnViX3VpbnQzMl90IHNlZ19vZmYsIGJsb2NrX29mZiwgZW50 cnlfb2ZmLCBibG9ja19hZGRyOworICBncnViX3VpbnQzMl90IGJsa2FkZHI7CisgIGdydWJfZXJy X3QgZXJyOworCisgIGJsa2FkZHIgPSBnZXRfYmxrYWRkcl9mcm9tX25hdF9qb3VybmFsIChkYXRh LCBuaWQpOworICBpZiAoYmxrYWRkcikKKyAgICByZXR1cm4gYmxrYWRkcjsKKworICBuYXRfYmxv Y2sgPSBncnViX21hbGxvYyAoRjJGU19CTEtTSVpFKTsKKyAgaWYgKCFuYXRfYmxvY2spCisgICAg cmV0dXJuIDA7CisKKyAgYmxvY2tfb2ZmID0gbmlkIC8gTkFUX0VOVFJZX1BFUl9CTE9DSzsKKyAg ZW50cnlfb2ZmID0gbmlkICUgTkFUX0VOVFJZX1BFUl9CTE9DSzsKKworICBzZWdfb2ZmID0gYmxv Y2tfb2ZmIC8gZGF0YS0+YmxvY2tzX3Blcl9zZWc7CisgIGJsb2NrX2FkZHIgPSBkYXRhLT5uYXRf YmxrYWRkciArCisJKChzZWdfb2ZmICogZGF0YS0+YmxvY2tzX3Blcl9zZWcpIDw8IDEpICsKKwko YmxvY2tfb2ZmICYgKGRhdGEtPmJsb2Nrc19wZXJfc2VnIC0gMSkpOworCisgIGlmIChncnViX2Yy ZnNfdGVzdF9iaXQgKGJsb2NrX29mZiwgZGF0YS0+bmF0X2JpdG1hcCkpCisgICAgYmxvY2tfYWRk ciArPSBkYXRhLT5ibG9ja3NfcGVyX3NlZzsKKworICBlcnIgPSBncnViX2YyZnNfYmxvY2tfcmVh ZCAoZGF0YSwgYmxvY2tfYWRkciwgbmF0X2Jsb2NrKTsKKyAgaWYgKGVycikKKyAgICB7CisgICAg ICBncnViX2ZyZWUgKG5hdF9ibG9jayk7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgYmxr YWRkciA9IGdydWJfbGVfdG9fY3B1MzIgKG5hdF9ibG9jay0+bmVbZW50cnlfb2ZmXS5ibG9ja19h ZGRyKTsKKworICBncnViX2ZyZWUgKG5hdF9ibG9jayk7CisKKyAgcmV0dXJuIGJsa2FkZHI7Cit9 CisKK3N0YXRpYyBpbnQKK2dydWJfZ2V0X25vZGVfcGF0aCAoc3RydWN0IGdydWJfZjJmc19pbm9k ZSAqaW5vZGUsIGdydWJfdWludDMyX3QgYmxvY2ssCisJZ3J1Yl91aW50MzJfdCBvZmZzZXRbNF0s IGdydWJfdWludDMyX3Qgbm9mZnNldFs0XSkKK3sKKyAgZ3J1Yl91aW50MzJfdCBkaXJlY3RfYmxr cyA9IEFERFJTX1BFUl9CTE9DSzsKKyAgZ3J1Yl91aW50MzJfdCBkcHRyc19wZXJfYmxrID0gTklE U19QRVJfQkxPQ0s7CisgIGdydWJfdWludDMyX3QgaW5kaXJlY3RfYmxrcyA9IEFERFJTX1BFUl9C TE9DSyAqIE5JRFNfUEVSX0JMT0NLOworICBncnViX3VpbnQzMl90IGRpbmRpcmVjdF9ibGtzID0g aW5kaXJlY3RfYmxrcyAqIE5JRFNfUEVSX0JMT0NLOworICBncnViX3VpbnQzMl90IGRpcmVjdF9p bmRleCA9IERFRl9BRERSU19QRVJfSU5PREU7CisgIGludCBuID0gMDsKKyAgaW50IGxldmVsID0g MDsKKworICBpZiAoaW5vZGUtPmlfaW5saW5lICYgRjJGU19JTkxJTkVfWEFUVFIpCisgICAgZGly ZWN0X2luZGV4IC09IEYyRlNfSU5MSU5FX1hBVFRSX0FERFJTOworCisgIG5vZmZzZXRbMF0gPSAw OworCisgIGlmIChibG9jayA8IGRpcmVjdF9pbmRleCkKKyAgICB7CisgICAgICBvZmZzZXRbbl0g PSBibG9jazsKKyAgICAgIGdvdG8gZ290OworICAgIH0KKworICBibG9jayAtPSBkaXJlY3RfaW5k ZXg7CisgIGlmIChibG9jayA8IGRpcmVjdF9ibGtzKQorICAgIHsKKyAgICAgIG9mZnNldFtuKytd ID0gTk9ERV9ESVIxX0JMT0NLOworICAgICAgbm9mZnNldFtuXSA9IDE7CisgICAgICBvZmZzZXRb bl0gPSBibG9jazsKKyAgICAgIGxldmVsID0gMTsKKyAgICAgIGdvdG8gZ290OworICAgIH0KKwor ICBibG9jayAtPSBkaXJlY3RfYmxrczsKKyAgaWYgKGJsb2NrIDwgZGlyZWN0X2Jsa3MpCisgICAg eworICAgICAgb2Zmc2V0W24rK10gPSBOT0RFX0RJUjJfQkxPQ0s7CisgICAgICBub2Zmc2V0W25d ID0gMjsKKyAgICAgIG9mZnNldFtuXSA9IGJsb2NrOworICAgICAgbGV2ZWwgPSAxOworICAgICAg Z290byBnb3Q7CisgICAgfQorCisgIGJsb2NrIC09IGRpcmVjdF9ibGtzOworICBpZiAoYmxvY2sg PCBpbmRpcmVjdF9ibGtzKQorICAgIHsKKyAgICAgIG9mZnNldFtuKytdID0gTk9ERV9JTkQxX0JM T0NLOworICAgICAgbm9mZnNldFtuXSA9IDM7CisgICAgICBvZmZzZXRbbisrXSA9IGJsb2NrIC8g ZGlyZWN0X2Jsa3M7CisgICAgICBub2Zmc2V0W25dID0gNCArIG9mZnNldFtuIC0gMV07CisgICAg ICBvZmZzZXRbbl0gPSBibG9jayAlIGRpcmVjdF9ibGtzOworICAgICAgbGV2ZWwgPSAyOworICAg ICAgZ290byBnb3Q7CisgICAgfQorCisgIGJsb2NrIC09IGluZGlyZWN0X2Jsa3M7CisgIGlmIChi bG9jayA8IGluZGlyZWN0X2Jsa3MpCisgICAgeworICAgICAgb2Zmc2V0W24rK10gPSBOT0RFX0lO RDJfQkxPQ0s7CisgICAgICBub2Zmc2V0W25dID0gNCArIGRwdHJzX3Blcl9ibGs7CisgICAgICBv ZmZzZXRbbisrXSA9IGJsb2NrIC8gZGlyZWN0X2Jsa3M7CisgICAgICBub2Zmc2V0W25dID0gNSAr IGRwdHJzX3Blcl9ibGsgKyBvZmZzZXRbbiAtIDFdOworICAgICAgb2Zmc2V0W25dID0gYmxvY2sg JSBkaXJlY3RfYmxrczsKKyAgICAgIGxldmVsID0gMjsKKyAgICAgIGdvdG8gZ290OworICAgIH0K KworICBibG9jayAtPSBpbmRpcmVjdF9ibGtzOworICBpZiAoYmxvY2sgPCBkaW5kaXJlY3RfYmxr cykKKyAgICB7CisgICAgICBvZmZzZXRbbisrXSA9IE5PREVfRElORF9CTE9DSzsKKyAgICAgIG5v ZmZzZXRbbl0gPSA1ICsgKGRwdHJzX3Blcl9ibGsgKiAyKTsKKyAgICAgIG9mZnNldFtuKytdID0g YmxvY2sgLyBpbmRpcmVjdF9ibGtzOworICAgICAgbm9mZnNldFtuXSA9IDYgKyAoZHB0cnNfcGVy X2JsayAqIDIpICsKKyAgICAgIG9mZnNldFtuIC0gMV0gKiAoZHB0cnNfcGVyX2JsayArIDEpOwor ICAgICAgb2Zmc2V0W24rK10gPSAoYmxvY2sgLyBkaXJlY3RfYmxrcykgJSBkcHRyc19wZXJfYmxr OworICAgICAgbm9mZnNldFtuXSA9IDcgKyAoZHB0cnNfcGVyX2JsayAqIDIpICsKKwkJb2Zmc2V0 W24gLSAyXSAqIChkcHRyc19wZXJfYmxrICsgMSkgKyBvZmZzZXRbbiAtIDFdOworICAgICAgb2Zm c2V0W25dID0gYmxvY2sgJSBkaXJlY3RfYmxrczsKKyAgICAgIGxldmVsID0gMzsKKyAgICAgIGdv dG8gZ290OworICAgIH0KK2dvdDoKKyAgcmV0dXJuIGxldmVsOworfQorCitzdGF0aWMgZ3J1Yl9l cnJfdAorZ3J1Yl9mMmZzX3JlYWRfbm9kZSAoc3RydWN0IGdydWJfZjJmc19kYXRhICpkYXRhLAor CWdydWJfdWludDMyX3QgbmlkLCBzdHJ1Y3QgZ3J1Yl9mMmZzX25vZGUgKm5wKQoreworICBncnVi X3VpbnQzMl90IGJsa2FkZHI7CisKKyAgYmxrYWRkciA9IGdldF9ub2RlX2Jsa2FkZHIgKGRhdGEs IG5pZCk7CisgIGlmICghYmxrYWRkcikKKyAgICByZXR1cm4gZ3J1Yl9lcnJubzsKKworICByZXR1 cm4gZ3J1Yl9mMmZzX2Jsb2NrX3JlYWQgKGRhdGEsIGJsa2FkZHIsIG5wKTsKK30KKworc3RhdGlj IHN0cnVjdCBncnViX2YyZnNfZGF0YSAqCitncnViX2YyZnNfbW91bnQgKGdydWJfZGlza190IGRp c2spCit7CisgIHN0cnVjdCBncnViX2YyZnNfZGF0YSAqZGF0YTsKKyAgZ3J1Yl9lcnJfdCBlcnI7 CisKKyAgZGF0YSA9IGdydWJfbWFsbG9jIChzaXplb2YgKCpkYXRhKSk7CisgIGlmICghZGF0YSkK KyAgICByZXR1cm4gTlVMTDsKKworICBkYXRhLT5kaXNrID0gZGlzazsKKworICBpZiAoZ3J1Yl9m MmZzX3JlYWRfc2IgKGRhdGEsIEYyRlNfU1VQRVJfT0ZGU0VUMCkpCisgICAgeworICAgICAgaWYg KGdydWJfZjJmc19yZWFkX3NiIChkYXRhLCBGMkZTX1NVUEVSX09GRlNFVDEpKQorICAgICAgICB7 CisgICAgICAgICAgaWYgKGdydWJfZXJybm8gPT0gR1JVQl9FUlJfTk9ORSkKKyAgICAgICAgICAg IGdydWJfZXJyb3IgKEdSVUJfRVJSX0JBRF9GUywKKwkJCSJub3QgYSBGMkZTIGZpbGVzeXN0ZW0g KG5vIHN1cGVyYmxvY2spIik7CisgICAgICAgICAgZ290byBmYWlsOworICAgICAgICB9CisgICAg fQorCisgIGRhdGEtPnJvb3RfaW5vID0gZ3J1Yl9sZV90b19jcHUzMiAoZGF0YS0+c2Jsb2NrLnJv b3RfaW5vKTsKKyAgZGF0YS0+Y3BfYmxrYWRkciA9IGdydWJfbGVfdG9fY3B1MzIgKGRhdGEtPnNi bG9jay5jcF9ibGthZGRyKTsKKyAgZGF0YS0+bmF0X2Jsa2FkZHIgPSBncnViX2xlX3RvX2NwdTMy IChkYXRhLT5zYmxvY2submF0X2Jsa2FkZHIpOworICBkYXRhLT5ibG9ja3NfcGVyX3NlZyA9IDEg PDwKKwlncnViX2xlX3RvX2NwdTMyIChkYXRhLT5zYmxvY2subG9nX2Jsb2Nrc19wZXJfc2VnKTsK KworICBlcnIgPSBncnViX2YyZnNfcmVhZF9jcCAoZGF0YSk7CisgIGlmIChlcnIpCisgICAgZ290 byBmYWlsOworCisgIGRhdGEtPm5hdF9iaXRtYXAgPSBfX25hdF9iaXRtYXBfcHRyIChkYXRhKTsK KworICBlcnIgPSBnZXRfbmF0X2pvdXJuYWwgKGRhdGEpOworICBpZiAoZXJyKQorICAgIGdvdG8g ZmFpbDsKKworICBkYXRhLT5kaXJvcGVuLmRhdGEgPSBkYXRhOworICBkYXRhLT5kaXJvcGVuLmlu byA9IGRhdGEtPnJvb3RfaW5vOworICBkYXRhLT5kaXJvcGVuLmlub2RlX3JlYWQgPSAxOworICBk YXRhLT5pbm9kZSA9ICZkYXRhLT5kaXJvcGVuLmlub2RlOworCisgIGVyciA9IGdydWJfZjJmc19y ZWFkX25vZGUgKGRhdGEsIGRhdGEtPnJvb3RfaW5vLCBkYXRhLT5pbm9kZSk7CisgIGlmIChlcnIp CisgICAgZ290byBmYWlsOworCisgIHJldHVybiBkYXRhOworCitmYWlsOgorICBncnViX2ZyZWUg KGRhdGEpOworICByZXR1cm4gTlVMTDsKK30KKworLyogZ3VhcmFudGVlIGlubGluZV9kYXRhIHdh cyBoYW5kbGVkIGJ5IGNhbGxlciAqLworc3RhdGljIGdydWJfZGlza19hZGRyX3QKK2dydWJfZjJm c19nZXRfYmxvY2sgKGdydWJfZnNoZWxwX25vZGVfdCBub2RlLCBncnViX2Rpc2tfYWRkcl90IGJs b2NrX29mcykKK3sKKyAgc3RydWN0IGdydWJfZjJmc19kYXRhICpkYXRhID0gbm9kZS0+ZGF0YTsK KyAgc3RydWN0IGdydWJfZjJmc19pbm9kZSAqaW5vZGUgPSAmbm9kZS0+aW5vZGUuaTsKKyAgZ3J1 Yl91aW50MzJfdCBvZmZzZXRbNF0sIG5vZmZzZXRbNF0sIG5pZHNbNF07CisgIHN0cnVjdCBncnVi X2YyZnNfbm9kZSAqbm9kZV9ibG9jazsKKyAgZ3J1Yl91aW50MzJfdCBibG9ja19hZGRyID0gLTE7 CisgIGludCBsZXZlbCwgaTsKKworICBsZXZlbCA9IGdydWJfZ2V0X25vZGVfcGF0aCAoaW5vZGUs IGJsb2NrX29mcywgb2Zmc2V0LCBub2Zmc2V0KTsKKyAgaWYgKGxldmVsID09IDApCisgICAgcmV0 dXJuIGdydWJfbGVfdG9fY3B1MzIgKGlub2RlLT5pX2FkZHJbb2Zmc2V0WzBdXSk7CisKKyAgbm9k ZV9ibG9jayA9IGdydWJfbWFsbG9jIChGMkZTX0JMS1NJWkUpOworICBpZiAoIW5vZGVfYmxvY2sp CisgICAgcmV0dXJuIC0xOworCisgIG5pZHNbMV0gPSBfX2dldF9ub2RlX2lkICgmbm9kZS0+aW5v ZGUsIG9mZnNldFswXSwgMSk7CisKKyAgLyogZ2V0IGluZGlyZWN0IG9yIGRpcmVjdCBub2RlcyAq LworICBmb3IgKGkgPSAxOyBpIDw9IGxldmVsOyBpKyspCisgICAgeworICAgICAgZ3J1Yl9mMmZz X3JlYWRfbm9kZSAoZGF0YSwgbmlkc1tpXSwgbm9kZV9ibG9jayk7CisgICAgICBpZiAoZ3J1Yl9l cnJubykKKyAgICAgICAgZ290byBmYWlsOworCisgICAgICBpZiAoaSA8IGxldmVsKQorICAgICAg ICBuaWRzW2kgKyAxXSA9IF9fZ2V0X25vZGVfaWQgKG5vZGVfYmxvY2ssIG9mZnNldFtpXSwgMCk7 CisgICAgfQorCisgIGJsb2NrX2FkZHIgPSBncnViX2xlX3RvX2NwdTMyIChub2RlX2Jsb2NrLT5k bi5hZGRyW29mZnNldFtsZXZlbF1dKTsKK2ZhaWw6CisgIGdydWJfZnJlZSAobm9kZV9ibG9jayk7 CisgIHJldHVybiBibG9ja19hZGRyOworfQorCitzdGF0aWMgZ3J1Yl9zc2l6ZV90CitncnViX2Yy ZnNfcmVhZF9maWxlIChncnViX2ZzaGVscF9ub2RlX3Qgbm9kZSwKKwkJZ3J1Yl9kaXNrX3JlYWRf aG9va190IHJlYWRfaG9vaywgdm9pZCAqcmVhZF9ob29rX2RhdGEsCisJCWdydWJfb2ZmX3QgcG9z LCBncnViX3NpemVfdCBsZW4sIGNoYXIgKmJ1ZikKK3sKKyAgc3RydWN0IGdydWJfZjJmc19pbm9k ZSAqaW5vZGUgPSAmbm9kZS0+aW5vZGUuaTsKKyAgZ3J1Yl9vZmZfdCBmaWxlc2l6ZSA9IGdydWJf ZjJmc19maWxlX3NpemUgKGlub2RlKTsKKyAgY2hhciAqaW5saW5lX2FkZHIgPSBfX2lubGluZV9h ZGRyIChpbm9kZSk7CisKKyAgaWYgKGlub2RlLT5pX2lubGluZSAmIEYyRlNfSU5MSU5FX0RBVEEp CisgICAgeworICAgICAgaWYgKHBvcyA+IGZpbGVzaXplIHx8IGZpbGVzaXplID4gTUFYX0lOTElO RV9EQVRBKQorICAgICAgICB7CisgICAgICAgICAgZ3J1Yl9lcnJvciAoR1JVQl9FUlJfQkFEX0ZT LCAiY29ycnVwdGVkIGlubGluZV9kYXRhOiBuZWVkIGZzY2siKTsKKyAgICAgICAgICByZXR1cm4g LTE7CisgICAgICAgIH0KKyAgICAgIGlmIChsZW4gPiBmaWxlc2l6ZSAtIHBvcykKKyAgICAgICAg bGVuID0gZmlsZXNpemUgLSBwb3M7CisKKyAgICAgIGdydWJfbWVtY3B5IChidWYgKyBwb3MsIGlu bGluZV9hZGRyICsgcG9zLCBsZW4pOworICAgICAgcmV0dXJuIGxlbjsKKyAgICB9CisKKyAgcmV0 dXJuIGdydWJfZnNoZWxwX3JlYWRfZmlsZSAobm9kZS0+ZGF0YS0+ZGlzaywgbm9kZSwKKwkJCXJl YWRfaG9vaywgcmVhZF9ob29rX2RhdGEsCisJCQlwb3MsIGxlbiwgYnVmLCBncnViX2YyZnNfZ2V0 X2Jsb2NrLAorCQkJZmlsZXNpemUsCisJCQlGMkZTX0JMS19TRUNfQklUUywgMCk7Cit9CisKK3N0 YXRpYyBjaGFyICoKK2dydWJfZjJmc19yZWFkX3N5bWxpbmsgKGdydWJfZnNoZWxwX25vZGVfdCBu b2RlKQoreworICBjaGFyICpzeW1saW5rOworICBzdHJ1Y3QgZ3J1Yl9mc2hlbHBfbm9kZSAqZGly byA9IG5vZGU7CisgIGdydWJfdWludDY0X3QgZmlsZXNpemU7CisKKyAgaWYgKCFkaXJvLT5pbm9k ZV9yZWFkKQorICAgIHsKKyAgICAgIGdydWJfZjJmc19yZWFkX25vZGUgKGRpcm8tPmRhdGEsIGRp cm8tPmlubywgJmRpcm8tPmlub2RlKTsKKyAgICAgIGlmIChncnViX2Vycm5vKQorICAgICAgICBy ZXR1cm4gMDsKKyAgICB9CisKKyAgZmlsZXNpemUgPSBncnViX2YyZnNfZmlsZV9zaXplKCZkaXJv LT5pbm9kZS5pKTsKKworICBzeW1saW5rID0gZ3J1Yl9tYWxsb2MgKGZpbGVzaXplICsgMSk7Cisg IGlmICghc3ltbGluaykKKyAgICByZXR1cm4gMDsKKworICBncnViX2YyZnNfcmVhZF9maWxlIChk aXJvLCAwLCAwLCAwLCBmaWxlc2l6ZSwgc3ltbGluayk7CisgIGlmIChncnViX2Vycm5vKQorICAg IHsKKyAgICAgIGdydWJfZnJlZSAoc3ltbGluayk7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisK KyAgc3ltbGlua1tmaWxlc2l6ZV0gPSAnXDAnOworICByZXR1cm4gc3ltbGluazsKK30KKworc3Rh dGljIGludAorZ3J1Yl9mMmZzX2NoZWNrX2RlbnRyaWVzIChzdHJ1Y3QgZ3J1Yl9mMmZzX2Rpcl9p dGVyX2N0eCAqY3R4KQoreworICBzdHJ1Y3QgZ3J1Yl9mc2hlbHBfbm9kZSAqZmRpcm87CisgIGlu dCBpOworCisgIGZvciAoaSA9IDA7IGkgPCBjdHgtPm1heDspCisgICAgeworICAgICAgY2hhciAq ZmlsZW5hbWU7CisgICAgICBlbnVtIGdydWJfZnNoZWxwX2ZpbGV0eXBlIHR5cGUgPSBHUlVCX0ZT SEVMUF9VTktOT1dOOworICAgICAgZW51bSBGSUxFX1RZUEUgZnR5cGU7CisgICAgICBpbnQgbmFt ZV9sZW47CisgICAgICBpbnQgcmV0OworCisgICAgICBpZiAoZ3J1Yl9nZW5lcmljX3Rlc3RfYml0 IChpLCBjdHgtPmJpdG1hcCkgPT0gMCkKKyAgICAgICAgeworICAgICAgICAgIGkrKzsKKyAgICAg ICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICBmdHlwZSA9IGN0eC0+ZGVudHJ5W2ld LmZpbGVfdHlwZTsKKyAgICAgIG5hbWVfbGVuID0gZ3J1Yl9sZV90b19jcHUxNiAoY3R4LT5kZW50 cnlbaV0ubmFtZV9sZW4pOworICAgICAgZmlsZW5hbWUgPSBncnViX21hbGxvYyAobmFtZV9sZW4g KyAxKTsKKyAgICAgIGlmICghZmlsZW5hbWUpCisgICAgICAgIHJldHVybiAwOworCisgICAgICBn cnViX21lbWNweSAoZmlsZW5hbWUsIGN0eC0+ZmlsZW5hbWVbaV0sIG5hbWVfbGVuKTsKKyAgICAg IGZpbGVuYW1lW25hbWVfbGVuXSA9IDA7CisKKyAgICAgIGZkaXJvID0gZ3J1Yl9tYWxsb2MgKHNp emVvZiAoc3RydWN0IGdydWJfZnNoZWxwX25vZGUpKTsKKyAgICAgIGlmICghZmRpcm8pCisgICAg ICAgIHsKKyAgICAgICAgICBncnViX2ZyZWUoZmlsZW5hbWUpOworICAgICAgICAgIHJldHVybiAw OworICAgICAgICB9CisKKyAgICAgIGlmIChmdHlwZSA9PSBGMkZTX0ZUX0RJUikKKyAgICAgICAg dHlwZSA9IEdSVUJfRlNIRUxQX0RJUjsKKyAgICAgIGVsc2UgaWYgKGZ0eXBlID09IEYyRlNfRlRf U1lNTElOSykKKyAgICAgICAgdHlwZSA9IEdSVUJfRlNIRUxQX1NZTUxJTks7CisgICAgICBlbHNl IGlmIChmdHlwZSA9PSBGMkZTX0ZUX1JFR19GSUxFKQorICAgICAgICB0eXBlID0gR1JVQl9GU0hF TFBfUkVHOworCisgICAgICBmZGlyby0+ZGF0YSA9IGN0eC0+ZGF0YTsKKyAgICAgIGZkaXJvLT5p bm8gPSBncnViX2xlX3RvX2NwdTMyIChjdHgtPmRlbnRyeVtpXS5pbm8pOworICAgICAgZmRpcm8t Pmlub2RlX3JlYWQgPSAwOworCisgICAgICByZXQgPSBjdHgtPmhvb2sgKGZpbGVuYW1lLCB0eXBl LCBmZGlybywgY3R4LT5ob29rX2RhdGEpOworICAgICAgZ3J1Yl9mcmVlKGZpbGVuYW1lKTsKKyAg ICAgIGlmIChyZXQpCisgICAgICAgIHJldHVybiAxOworCisgICAgICBpICs9IChuYW1lX2xlbiAr IEYyRlNfU0xPVF9MRU4gLSAxKSAvIEYyRlNfU0xPVF9MRU47CisgICAgfQorICAgIHJldHVybiAw OworfQorCitzdGF0aWMgaW50CitncnViX2YyZnNfaXRlcmF0ZV9pbmxpbmVfZGlyIChzdHJ1Y3Qg Z3J1Yl9mMmZzX2lub2RlICpkaXIsCisJc3RydWN0IGdydWJfZjJmc19kaXJfaXRlcl9jdHggKmN0 eCkKK3sKKyAgc3RydWN0IGdydWJfZjJmc19pbmxpbmVfZGVudHJ5ICpkZV9ibGs7CisKKyAgZGVf YmxrID0gKHN0cnVjdCBncnViX2YyZnNfaW5saW5lX2RlbnRyeSAqKSBfX2lubGluZV9hZGRyIChk aXIpOworCisgIGN0eC0+Yml0bWFwID0gKGdydWJfdWludDMyX3QgKikgZGVfYmxrLT5kZW50cnlf Yml0bWFwOworICBjdHgtPmRlbnRyeSA9IGRlX2Jsay0+ZGVudHJ5OworICBjdHgtPmZpbGVuYW1l ID0gZGVfYmxrLT5maWxlbmFtZTsKKyAgY3R4LT5tYXggPSBOUl9JTkxJTkVfREVOVFJZOworCisg IHJldHVybiBncnViX2YyZnNfY2hlY2tfZGVudHJpZXMgKGN0eCk7Cit9CisKK3N0YXRpYyBpbnQK K2dydWJfZjJmc19pdGVyYXRlX2RpciAoZ3J1Yl9mc2hlbHBfbm9kZV90IGRpciwKKwlncnViX2Zz aGVscF9pdGVyYXRlX2Rpcl9ob29rX3QgaG9vaywgdm9pZCAqaG9va19kYXRhKQoreworICBzdHJ1 Y3QgZ3J1Yl9mc2hlbHBfbm9kZSAqZGlybyA9IChzdHJ1Y3QgZ3J1Yl9mc2hlbHBfbm9kZSAqKSBk aXI7CisgIHN0cnVjdCBncnViX2YyZnNfaW5vZGUgKmlub2RlOworICBzdHJ1Y3QgZ3J1Yl9mMmZz X2Rpcl9pdGVyX2N0eCBjdHggPSB7CisgICAgLmRhdGEgPSBkaXJvLT5kYXRhLAorICAgIC5ob29r ID0gaG9vaywKKyAgICAuaG9va19kYXRhID0gaG9va19kYXRhCisgIH07CisgIGdydWJfb2ZmX3Qg ZnBvcyA9IDA7CisKKyAgaWYgKCFkaXJvLT5pbm9kZV9yZWFkKQorICAgIHsKKyAgICAgIGdydWJf ZjJmc19yZWFkX25vZGUgKGRpcm8tPmRhdGEsIGRpcm8tPmlubywgJmRpcm8tPmlub2RlKTsKKyAg ICAgIGlmIChncnViX2Vycm5vKQorCXJldHVybiAwOworICAgIH0KKworICBpbm9kZSA9ICZkaXJv LT5pbm9kZS5pOworCisgIGlmIChpbm9kZS0+aV9pbmxpbmUgJiBGMkZTX0lOTElORV9ERU5UUlkp CisgICAgcmV0dXJuIGdydWJfZjJmc19pdGVyYXRlX2lubGluZV9kaXIgKGlub2RlLCAmY3R4KTsK KworICB3aGlsZSAoZnBvcyA8IGdydWJfZjJmc19maWxlX3NpemUgKGlub2RlKSkKKyAgICB7Cisg ICAgICBzdHJ1Y3QgZ3J1Yl9mMmZzX2RlbnRyeV9ibG9jayAqZGVfYmxrOworICAgICAgY2hhciAq YnVmOworICAgICAgaW50IHJldDsKKworICAgICAgYnVmID0gZ3J1Yl96YWxsb2MgKEYyRlNfQkxL U0laRSk7CisgICAgICBpZiAoIWJ1ZikKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgIGdydWJf ZjJmc19yZWFkX2ZpbGUgKGRpcm8sIDAsIDAsIGZwb3MsIEYyRlNfQkxLU0laRSwgYnVmKTsKKyAg ICAgIGlmIChncnViX2Vycm5vKQorICAgICAgICB7CisgICAgICAgICAgZ3J1Yl9mcmVlIChidWYp OworICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgIGRlX2JsayA9IChzdHJ1 Y3QgZ3J1Yl9mMmZzX2RlbnRyeV9ibG9jayAqKSBidWY7CisKKyAgICAgIGN0eC5iaXRtYXAgPSAo Z3J1Yl91aW50MzJfdCAqKSBkZV9ibGstPmRlbnRyeV9iaXRtYXA7CisgICAgICBjdHguZGVudHJ5 ID0gZGVfYmxrLT5kZW50cnk7CisgICAgICBjdHguZmlsZW5hbWUgPSBkZV9ibGstPmZpbGVuYW1l OworICAgICAgY3R4Lm1heCA9IE5SX0RFTlRSWV9JTl9CTE9DSzsKKworICAgICAgcmV0ID0gZ3J1 Yl9mMmZzX2NoZWNrX2RlbnRyaWVzICgmY3R4KTsKKyAgICAgIGdydWJfZnJlZSAoYnVmKTsKKyAg ICAgIGlmIChyZXQpCisgICAgICAgIHJldHVybiAxOworCisgICAgICBmcG9zICs9IEYyRlNfQkxL U0laRTsKKyAgICB9CisgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CitncnViX2YyZnNfZGly X2l0ZXIgKGNvbnN0IGNoYXIgKmZpbGVuYW1lLCBlbnVtIGdydWJfZnNoZWxwX2ZpbGV0eXBlIGZp bGV0eXBlLAorCSAgICAgIGdydWJfZnNoZWxwX25vZGVfdCBub2RlLCB2b2lkICpkYXRhKQorewor ICBzdHJ1Y3QgZ3J1Yl9mMmZzX2Rpcl9jdHggKmN0eCA9IGRhdGE7CisgIHN0cnVjdCBncnViX2Rp cmhvb2tfaW5mbyBpbmZvOworCisgIGdydWJfbWVtc2V0ICgmaW5mbywgMCwgc2l6ZW9mIChpbmZv KSk7CisgIGlmICghbm9kZS0+aW5vZGVfcmVhZCkKKyAgICB7CisgICAgICBncnViX2YyZnNfcmVh ZF9ub2RlIChjdHgtPmRhdGEsIG5vZGUtPmlubywgJm5vZGUtPmlub2RlKTsKKyAgICAgIGlmICgh Z3J1Yl9lcnJubykKKyAgICAgICAgbm9kZS0+aW5vZGVfcmVhZCA9IDE7CisgICAgICBncnViX2Vy cm5vID0gR1JVQl9FUlJfTk9ORTsKKyAgICB9CisgIGlmIChub2RlLT5pbm9kZV9yZWFkKQorICAg IHsKKyAgICAgIGluZm8ubXRpbWVzZXQgPSAxOworICAgICAgaW5mby5tdGltZSA9IGdydWJfbGVf dG9fY3B1NjQgKG5vZGUtPmlub2RlLmkuaV9tdGltZSk7CisgICAgfQorCisgIGluZm8uZGlyID0g KChmaWxldHlwZSAmIEdSVUJfRlNIRUxQX1RZUEVfTUFTSykgPT0gR1JVQl9GU0hFTFBfRElSKTsK KyAgZ3J1Yl9mcmVlIChub2RlKTsKKyAgcmV0dXJuIGN0eC0+aG9vayAoZmlsZW5hbWUsICZpbmZv LCBjdHgtPmhvb2tfZGF0YSk7Cit9CisKK3N0YXRpYyBncnViX2Vycl90CitncnViX2YyZnNfZGly IChncnViX2RldmljZV90IGRldmljZSwgY29uc3QgY2hhciAqcGF0aCwKKwlncnViX2ZzX2Rpcl9o b29rX3QgaG9vaywgdm9pZCAqaG9va19kYXRhKQoreworICBzdHJ1Y3QgZ3J1Yl9mMmZzX2Rpcl9j dHggY3R4ID0geworICAgIC5ob29rID0gaG9vaywKKyAgICAuaG9va19kYXRhID0gaG9va19kYXRh CisgIH07CisgIHN0cnVjdCBncnViX2ZzaGVscF9ub2RlICpmZGlybyA9IDA7CisKKyAgZ3J1Yl9k bF9yZWYgKG15X21vZCk7CisKKyAgY3R4LmRhdGEgPSBncnViX2YyZnNfbW91bnQgKGRldmljZS0+ ZGlzayk7CisgIGlmICghY3R4LmRhdGEpCisgICAgZ290byBmYWlsOworCisgIGdydWJfZnNoZWxw X2ZpbmRfZmlsZSAocGF0aCwgJmN0eC5kYXRhLT5kaXJvcGVuLCAmZmRpcm8sCisJCWdydWJfZjJm c19pdGVyYXRlX2RpciwgZ3J1Yl9mMmZzX3JlYWRfc3ltbGluaywKKwkJR1JVQl9GU0hFTFBfRElS KTsKKyAgaWYgKGdydWJfZXJybm8pCisgICAgZ290byBmYWlsOworCisgIGdydWJfZjJmc19pdGVy YXRlX2RpciAoZmRpcm8sIGdydWJfZjJmc19kaXJfaXRlciwgJmN0eCk7CisKK2ZhaWw6CisgIGlm IChmZGlybyAhPSAmY3R4LmRhdGEtPmRpcm9wZW4pCisgICAgZ3J1Yl9mcmVlIChmZGlybyk7Cisg Z3J1Yl9mcmVlIChjdHguZGF0YSk7CisgZ3J1Yl9kbF91bnJlZiAobXlfbW9kKTsKKyByZXR1cm4g Z3J1Yl9lcnJubzsKK30KKworCisvKiBPcGVuIGEgZmlsZSBuYW1lZCBOQU1FIGFuZCBpbml0aWFs aXplIEZJTEUuICAqLworc3RhdGljIGdydWJfZXJyX3QKK2dydWJfZjJmc19vcGVuIChzdHJ1Y3Qg Z3J1Yl9maWxlICpmaWxlLCBjb25zdCBjaGFyICpuYW1lKQoreworICBzdHJ1Y3QgZ3J1Yl9mMmZz X2RhdGEgKmRhdGEgPSBOVUxMOworICBzdHJ1Y3QgZ3J1Yl9mc2hlbHBfbm9kZSAqZmRpcm8gPSAw OworCisgIGdydWJfZGxfcmVmIChteV9tb2QpOworCisgIGRhdGEgPSBncnViX2YyZnNfbW91bnQg KGZpbGUtPmRldmljZS0+ZGlzayk7CisgIGlmICghZGF0YSkKKyAgICBnb3RvIGZhaWw7CisKKyAg Z3J1Yl9mc2hlbHBfZmluZF9maWxlIChuYW1lLCAmZGF0YS0+ZGlyb3BlbiwgJmZkaXJvLAorCQkJ Z3J1Yl9mMmZzX2l0ZXJhdGVfZGlyLCBncnViX2YyZnNfcmVhZF9zeW1saW5rLAorCQkJR1JVQl9G U0hFTFBfUkVHKTsKKyAgaWYgKGdydWJfZXJybm8pCisgICAgZ290byBmYWlsOworCisgIGlmICgh ZmRpcm8tPmlub2RlX3JlYWQpCisgICAgeworICAgICAgZ3J1Yl9mMmZzX3JlYWRfbm9kZSAoZGF0 YSwgZmRpcm8tPmlubywgJmZkaXJvLT5pbm9kZSk7CisgICAgICBpZiAoZ3J1Yl9lcnJubykKKwln b3RvIGZhaWw7CisgICAgfQorCisgIGdydWJfbWVtY3B5IChkYXRhLT5pbm9kZSwgJmZkaXJvLT5p bm9kZSwgc2l6ZW9mICgqZGF0YS0+aW5vZGUpKTsKKyAgZ3J1Yl9mcmVlIChmZGlybyk7CisKKyAg ZmlsZS0+c2l6ZSA9IGdydWJfZjJmc19maWxlX3NpemUgKCYoZGF0YS0+aW5vZGUtPmkpKTsKKyAg ZmlsZS0+ZGF0YSA9IGRhdGE7CisgIGZpbGUtPm9mZnNldCA9IDA7CisKKyAgcmV0dXJuIDA7CisK K2ZhaWw6CisgIGlmIChmZGlybyAhPSAmZGF0YS0+ZGlyb3BlbikKKyAgICBncnViX2ZyZWUgKGZk aXJvKTsKKyAgZ3J1Yl9mcmVlIChkYXRhKTsKKworICBncnViX2RsX3VucmVmIChteV9tb2QpOwor CisgIHJldHVybiBncnViX2Vycm5vOworfQorCitzdGF0aWMgZ3J1Yl9zc2l6ZV90CitncnViX2Yy ZnNfcmVhZCAoZ3J1Yl9maWxlX3QgZmlsZSwgY2hhciAqYnVmLCBncnViX3NpemVfdCBsZW4pCit7 CisgIHN0cnVjdCBncnViX2YyZnNfZGF0YSAqZGF0YSA9IChzdHJ1Y3QgZ3J1Yl9mMmZzX2RhdGEg KikgZmlsZS0+ZGF0YTsKKworICByZXR1cm4gZ3J1Yl9mMmZzX3JlYWRfZmlsZSAoJmRhdGEtPmRp cm9wZW4sCisJCWZpbGUtPnJlYWRfaG9vaywgZmlsZS0+cmVhZF9ob29rX2RhdGEsCisJCWZpbGUt Pm9mZnNldCwgbGVuLCBidWYpOworfQorCitzdGF0aWMgZ3J1Yl9lcnJfdAorZ3J1Yl9mMmZzX2Ns b3NlIChncnViX2ZpbGVfdCBmaWxlKQoreworICBzdHJ1Y3QgZ3J1Yl9mMmZzX2RhdGEgKmRhdGEg PSAoc3RydWN0IGdydWJfZjJmc19kYXRhICopIGZpbGUtPmRhdGE7CisKKyAgZ3J1Yl9mcmVlIChk YXRhKTsKKworICBncnViX2RsX3VucmVmIChteV9tb2QpOworCisgIHJldHVybiBHUlVCX0VSUl9O T05FOworfQorCisvKiBUT0RPOiBta2ZzLmYyZnMgc3RvcmVzIGxhYmVsIGluIGEgd3Jvbmcgd2F5 LiBTaG91bGQgYmUgZml4ZWQuICovCitzdGF0aWMgdm9pZAorZ3J1Yl9mMmZzX3VuaWNvZGVfdG9f YXNjaWkgKGdydWJfdWludDhfdCAqb3V0X2J1ZiwgZ3J1Yl91aW50MTZfdCAqaW5fYnVmKQorewor ICBncnViX3VpbnQxNl90ICpwY2hUZW1wUHRyID0gaW5fYnVmOworICBncnViX3VpbnQ4X3QgKnB3 VGVtcFB0ciA9IG91dF9idWY7CisKKyAgd2hpbGUgKCpwY2hUZW1wUHRyICE9ICdcMCcpCisgICAg eworICAgICAgKnB3VGVtcFB0ciA9IChncnViX3VpbnQ4X3QpICpwY2hUZW1wUHRyOworICAgICAg cGNoVGVtcFB0cisrOworICAgICAgcHdUZW1wUHRyKys7CisgICAgfQorICAqcHdUZW1wUHRyID0g J1wwJzsKKyAgcmV0dXJuOworfQorCitzdGF0aWMgZ3J1Yl9lcnJfdAorZ3J1Yl9mMmZzX2xhYmVs IChncnViX2RldmljZV90IGRldmljZSwgY2hhciAqKmxhYmVsKQoreworICBzdHJ1Y3QgZ3J1Yl9m MmZzX2RhdGEgKmRhdGE7CisgIGdydWJfZGlza190IGRpc2sgPSBkZXZpY2UtPmRpc2s7CisKKyAg Z3J1Yl9kbF9yZWYgKG15X21vZCk7CisKKyAgZGF0YSA9IGdydWJfZjJmc19tb3VudCAoZGlzayk7 CisgIGlmIChkYXRhKQorICAgIHsKKyAgICAgICpsYWJlbCA9IGdydWJfemFsbG9jIChzaXplb2Yg KGRhdGEtPnNibG9jay52b2x1bWVfbmFtZSkpOworICAgICAgaWYgKCpsYWJlbCkKKyAgICAgICAg Z3J1Yl9mMmZzX3VuaWNvZGVfdG9fYXNjaWkgKChncnViX3VpbnQ4X3QgKikgKCpsYWJlbCksCisJ CQlkYXRhLT5zYmxvY2sudm9sdW1lX25hbWUpOworICAgIH0KKyAgZWxzZQorICAgICpsYWJlbCA9 IE5VTEw7CisKKyAgZ3J1Yl9mcmVlIChkYXRhKTsKKyAgZ3J1Yl9kbF91bnJlZiAobXlfbW9kKTsK KyAgcmV0dXJuIGdydWJfZXJybm87Cit9CisKK3N0YXRpYyBncnViX2Vycl90CitncnViX2YyZnNf dXVpZCAoZ3J1Yl9kZXZpY2VfdCBkZXZpY2UsIGNoYXIgKip1dWlkKQoreworICBzdHJ1Y3QgZ3J1 Yl9mMmZzX2RhdGEgKmRhdGE7CisgIGdydWJfZGlza190IGRpc2sgPSBkZXZpY2UtPmRpc2s7CisK KyAgZ3J1Yl9kbF9yZWYgKG15X21vZCk7CisKKyAgZGF0YSA9IGdydWJfZjJmc19tb3VudCAoZGlz ayk7CisgIGlmIChkYXRhKQorICAgIHsKKyAgICAgICp1dWlkID0KKwlncnViX3hhc3ByaW50Zgor CSgiJTAyeCUwMnglMDJ4JTAyeC0lMDJ4JTAyeC0lMDJ4JTAyeC0lMDJ4JTAyeC0lMDJ4JTAyeCUw MnglMDJ4JTAyeCUwMngiLAorCQlkYXRhLT5zYmxvY2sudXVpZFswXSwgZGF0YS0+c2Jsb2NrLnV1 aWRbMV0sCisJCWRhdGEtPnNibG9jay51dWlkWzJdLCBkYXRhLT5zYmxvY2sudXVpZFszXSwKKwkJ ZGF0YS0+c2Jsb2NrLnV1aWRbNF0sIGRhdGEtPnNibG9jay51dWlkWzVdLAorCQlkYXRhLT5zYmxv Y2sudXVpZFs2XSwgZGF0YS0+c2Jsb2NrLnV1aWRbN10sCisJCWRhdGEtPnNibG9jay51dWlkWzhd LCBkYXRhLT5zYmxvY2sudXVpZFs5XSwKKwkJZGF0YS0+c2Jsb2NrLnV1aWRbMTBdLCBkYXRhLT5z YmxvY2sudXVpZFsxMV0sCisJCWRhdGEtPnNibG9jay51dWlkWzEyXSwgZGF0YS0+c2Jsb2NrLnV1 aWRbMTNdLAorCQlkYXRhLT5zYmxvY2sudXVpZFsxNF0sIGRhdGEtPnNibG9jay51dWlkWzE1XSk7 CisgICAgfQorICBlbHNlCisgICAgKnV1aWQgPSBOVUxMOworCisgIGdydWJfZnJlZSAoZGF0YSk7 CisgIGdydWJfZGxfdW5yZWYgKG15X21vZCk7CisgIHJldHVybiBncnViX2Vycm5vOworfQorCitz dGF0aWMgc3RydWN0IGdydWJfZnMgZ3J1Yl9mMmZzX2ZzID0geworICAubmFtZSA9ICJmMmZzIiwK KyAgLmRpciA9IGdydWJfZjJmc19kaXIsCisgIC5vcGVuID0gZ3J1Yl9mMmZzX29wZW4sCisgIC5y ZWFkID0gZ3J1Yl9mMmZzX3JlYWQsCisgIC5jbG9zZSA9IGdydWJfZjJmc19jbG9zZSwKKyAgLmxh YmVsID0gZ3J1Yl9mMmZzX2xhYmVsLAorICAudXVpZCA9IGdydWJfZjJmc191dWlkLAorI2lmZGVm IEdSVUJfVVRJTAorICAucmVzZXJ2ZWRfZmlyc3Rfc2VjdG9yID0gMSwKKyAgLmJsb2NrbGlzdF9p bnN0YWxsID0gMCwKKyNlbmRpZgorICAubmV4dCA9IDAKK307CisKK0dSVUJfTU9EX0lOSVQgKGYy ZnMpCit7CisgIGdydWJfZnNfcmVnaXN0ZXIgKCZncnViX2YyZnNfZnMpOworICBteV9tb2QgPSBt b2Q7Cit9CisKK0dSVUJfTU9EX0ZJTkkgKGYyZnMpCit7CisgIGdydWJfZnNfdW5yZWdpc3RlciAo JmdydWJfZjJmc19mcyk7Cit9CmRpZmYgLS1naXQgYS9wby9leGNsdWRlLnBvdCBiL3BvL2V4Y2x1 ZGUucG90CmluZGV4IDBhOWIyMTUuLjgxNjA4OWMgMTAwNjQ0Ci0tLSBhL3BvL2V4Y2x1ZGUucG90 CisrKyBiL3BvL2V4Y2x1ZGUucG90CkBAIC0xMjE0LDYgKzEyMTQsNyBAQCBtc2dzdHIgIiIKIAog IzogZ3J1Yi1jb3JlL2NvbW1hbmRzL3hudV91dWlkLmM6NzUgZ3J1Yi1jb3JlL2ZzL2pmcy5jOjky NAogIzogZ3J1Yi1jb3JlL2ZzL25pbGZzMi5jOjExMzUKKyM6IGdydWItY29yZS9mcy9mMmZzLmM6 MTI1OQogIywgYy1mb3JtYXQKIG1zZ2lkICIlMDJ4JTAyeCUwMnglMDJ4LSUwMnglMDJ4LSUwMngl MDJ4LSUwMnglMDJ4LSUwMnglMDJ4JTAyeCUwMnglMDJ4JTAyeCIKIG1zZ3N0ciAiIgpkaWZmIC0t Z2l0IGEvdGVzdHMvZjJmc190ZXN0LmluIGIvdGVzdHMvZjJmc190ZXN0LmluCm5ldyBmaWxlIG1v ZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFlYTc3YzgKLS0tIC9kZXYvbnVsbAorKysgYi90ZXN0 cy9mMmZzX3Rlc3QuaW4KQEAgLTAsMCArMSwxOSBAQAorIyEvYmluL3NoCisKK3NldCAtZQorCitp ZiBbICJ4JEVVSUQiID0gIngiIF0gOyB0aGVuCisgRVVJRD1gaWQgLXVgCitmaQorCitpZiBbICIk RVVJRCIgIT0gMCBdIDsgdGhlbgorIGV4aXQgNzcKK2ZpCisKK2lmICEgd2hpY2ggbWtmcy5mMmZz ID4vZGV2L251bGwgMj4mMTsgdGhlbgorIGVjaG8gIm1rZnMuZjJmcyBub3QgaW5zdGFsbGVkOyBj YW5ub3QgdGVzdCBmMmZzLiIKKyBleGl0IDc3CitmaQorCisKKyJAYnVpbGRkaXJAL2dydWItZnMt dGVzdGVyIiBmMmZzCmRpZmYgLS1naXQgYS90ZXN0cy91dGlsL2dydWItZnMtdGVzdGVyLmluIGIv dGVzdHMvdXRpbC9ncnViLWZzLXRlc3Rlci5pbgppbmRleCA0MjRkZTIyLi43MjQ1Y2I4IDEwMDY0 NAotLS0gYS90ZXN0cy91dGlsL2dydWItZnMtdGVzdGVyLmluCisrKyBiL3Rlc3RzL3V0aWwvZ3J1 Yi1mcy10ZXN0ZXIuaW4KQEAgLTE0Miw3ICsxNDIsNyBAQCBmb3IgKChMT0dTRUNTSVpFPU1JTkxP R1NFQ1NJWkU7TE9HU0VDU0laRTw9TUFYTE9HU0VDU0laRTtMT0dTRUNTSVpFPUxPR1NFQ1NJWkUg KwogCXhzcXVhc2gqKQogCSAgICBNSU5CTEtTSVpFPTQwOTYKIAkgICAgTUFYQkxLU0laRT0xMDQ4 NTc2OzsKLQl4eGZzKQorCXh4ZnN8eGYyZnMpCiAJICAgIE1JTkJMS1NJWkU9JFNFQ1NJWkUKIAkJ IyBPUyBMaW1pdGF0aW9uOiBHTlUvTGludXggZG9lc24ndCBhY2NlcHQgPiA0MDk2CiAJICAgIE1B WEJMS1NJWkU9NDA5Njs7CkBAIC0yNjUsNiArMjY1LDExIEBAIGZvciAoKExPR1NFQ1NJWkU9TUlO TE9HU0VDU0laRTtMT0dTRUNTSVpFPD1NQVhMT0dTRUNTSVpFO0xPR1NFQ1NJWkU9TE9HU0VDU0la RSArCiAJCXgiYnRyZnMiKikKIAkJICAgIEZTTEFCRUw9ImdydWJfOy90ZXN0w6nwr6ab8K+mnfCf mIHQutC40YDQuNGCaSB1cmV3ZmNlbml1ZXdydWV2cmV3bnV1aXJldXJldnVldXJuaWV2cmV3Zm5l cmZjbmV2aXJpdmlucmV3dm5pcmV3bml2cmV3aXV2Y3Jld3ZudWV3dnJycmV3bml1ZXJ3cmVpdXZp dXJld2l1dml1cmV3bnV2ZXdudnJlbnVybnVudXZyZXZ1dXJlcmVqaXJlbXZyZWlqbnZjcmVpdmly ZSBudmVyaXZucmVpdnJldm51cmVpb3JmbmZydm9lb2lyb2lyZW9pcmVvaWZyZWZvaWVyb2lmb2ly ZW9pZiI7OwogCisJICAgICMgRlMgTElNSVRBVElPTjogZjJmcyBsYWJlbCBpcyBhdCBtb3N0IDUx MiBVVEYtMTYgY2hhcnMKKwkgICAgIyBUT0RPOiBzZWVtcyB0aGF0IG1rZnMuZjJmcyBkb2Vzbid0 IGhhbmRsZSBlbmNvZGluZyBzdHVmZnMgY29ycmVjdGx5CisJCXgiZjJmcyIpCisJCSAgRlNMQUJF TD0iZ3J1Yl90ZXN0Om5vIHV0ZjE2Ijs7CisKIAkgICAgIyBGUyBMSU1JVEFUSU9OOiBleGZhdCBp cyBhdCBtb3N0IDE1IFVURi0xNiBjaGFycwogCQl4ImV4ZmF0IikKIAkJICAgIEZTTEFCRUw9ImfD qdGCIDsv8K+mm/Cvpp3wn5iB0LrQuNGAIjs7CkBAIC00NzQsNyArNDc5LDcgQEAgZm9yICgoTE9H U0VDU0laRT1NSU5MT0dTRUNTSVpFO0xPR1NFQ1NJWkU8PU1BWExPR1NFQ1NJWkU7TE9HU0VDU0la RT1MT0dTRUNTSVpFICsKIAkgICAgIyBGSVhNRTogTm90IHN1cmUgYWJvdXQgQnRyRlMsIE5URlMs IEpGUywgQUZTLCBVREYgYW5kIFNGUy4gQ2hlY2sgaXQuCiAJIyBGUyBMSU1JVEFUSU9OOiBhcyBm YXIgYXMgSSBrbm93IHRob3NlIEZTIGRvbid0IHN0b3JlIHRoZWlyIGxhc3QgbW9kaWZpY2F0aW9u IGRhdGUuCiAJCXgiamZzX2Nhc2VpbnMiIHwgeCJqZnMiIHwgeCJ4ZnMiIHwgeCJ4ZnNfY3JjIiB8 IHgiYnRyZnMiKiB8IHgicmVpc2VyZnNfb2xkIiB8IHgicmVpc2VyZnMiIFwKLQkJICAgIHwgeCJi ZnMiIHwgeCJhZnMiIFwKKwkJICAgIHwgeCJiZnMiIHwgeCJhZnMiIHwgeCJmMmZzIiBcCiAJCSAg ICB8IHgidGFyZnMiIHwgeCJjcGlvXyIqIHwgeCJtaW5peCIgfCB4Im1pbml4MiIgXAogCQkgICAg fCB4Im1pbml4MyIgfCB4Im50ZnMiKiB8IHgidWRmIiB8IHgic2ZzIiopCiAJCSAgICBOT0ZTVElN RT15OzsKQEAgLTc1Myw2ICs3NTgsOCBAQCBmb3IgKChMT0dTRUNTSVpFPU1JTkxPR1NFQ1NJWkU7 TE9HU0VDU0laRTw9TUFYTE9HU0VDU0laRTtMT0dTRUNTSVpFPUxPR1NFQ1NJWkUgKwogCQkgICAg TU9VTlRERVZJQ0U9Ii9kZXYvbWFwcGVyL2dydWJfdGVzdC10ZXN0dm9sIgogCQkgICAgTU9VTlRG Uz1leHQyCiAJCSAgICAibWtmcy5leHQyIiAtTCAiJEZTTEFCRUwiIC1xICIke01PVU5UREVWSUNF fSIgIDs7CisJCXhmMmZzKQorCQkgICAgIm1rZnMuZjJmcyIgLWwgIiRGU0xBQkVMIiAtcSAiJHtM T0RFVklDRVNbMF19IiA7OwogCQl4bmlsZnMyKQogCQkgICAgIm1rZnMubmlsZnMyIiAtTCAiJEZT TEFCRUwiIC1iICRCTEtTSVpFICAtcSAiJHtMT0RFVklDRVNbMF19IiA7OwogCQl4ZXh0Ml9vbGQp Ci0tIAoyLjQuOSAoQXBwbGUgR2l0LTYwKQoKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpMaW51eC1mMmZzLWRldmVs IG1haWxpbmcgbGlzdApMaW51eC1mMmZzLWRldmVsQGxpc3RzLnNvdXJjZWZvcmdlLm5ldApodHRw czovL2xpc3RzLnNvdXJjZWZvcmdlLm5ldC9saXN0cy9saXN0aW5mby9saW51eC1mMmZzLWRldmVs Cg==