From nobody Wed Oct 05 19:44:32 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MjQ5B5T2Dz4dwQ1 for ; Wed, 5 Oct 2022 19:44:46 +0000 (UTC) (envelope-from sobomax@sippysoft.com) Received: from mail-yb1-f179.google.com (mail-yb1-f179.google.com [209.85.219.179]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MjQ593kltz45pC for ; Wed, 5 Oct 2022 19:44:45 +0000 (UTC) (envelope-from sobomax@sippysoft.com) Received: by mail-yb1-f179.google.com with SMTP id 63so21535129ybq.4 for ; Wed, 05 Oct 2022 12:44:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=FN+xg+u/yY1qzZgP67HG9tKG+RiRAKMF7WdlMTFpoeo=; b=qV3F3RvD3WmvGlXSTCt+4ddTw6kDjckTTL9WFOZN0vfZt/JaF/PspKv7lyfmdts4iG os7bvwZqFiCusbKqGOF4kQeMDUiI2c9eErSNas/PDGs3To6JcJU/atAjE4MDdUVtf7GQ 53RGJeynx2aCs6XrPJ6V87olUQTw+EU9RzeqPVv9/tyJlb57N3ilPOniRE09fXuO9u9S SLQAPJaDBBWTJnt4dKihYXJ5wH5MRoXbPzo+JL+B6rvLImPw75/iFW77qEI7EWnNFOK0 A4acjTu25BDzed2nV8JHqmkk6h34np6sYEeCSzIqxGeFVdonlCjRMoGV0hyIEZk9WJlH MmCA== X-Gm-Message-State: ACrzQf0qv2fBO59NFDfrHx9hoqjyFOgZDlTnEaO5upSyNT0Oj4ahaLrn 3I83u5mxs6qQGId37Hprp/2eIfeVZTtIxZmoh2gpag== X-Google-Smtp-Source: AMsMyM77oybQMeuO0yxPVR3cLVSiBtCCIQE/MTSrhIolgYXYpH5JZ7RyZtEvzsDooRXKNTpjvvrc06BDNJ3zMujp4wY= X-Received: by 2002:a25:b94:0:b0:6be:6765:7e5 with SMTP id 142-20020a250b94000000b006be676507e5mr1343471ybl.561.1664999084233; Wed, 05 Oct 2022 12:44:44 -0700 (PDT) List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 References: <202209270004.28R04K1r086731@gitrepo.freebsd.org> In-Reply-To: From: Maxim Sobolev Date: Wed, 5 Oct 2022 12:44:32 -0700 Message-ID: Subject: Re: git: d3f96f661050 - main - Fix O(n^2) behavior in sysctl To: Alan Somers Cc: src-committers , dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org Content-Type: multipart/alternative; boundary="000000000000f7ae8605ea4ece83" X-Rspamd-Queue-Id: 4MjQ593kltz45pC X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org; dkim=none; dmarc=none; spf=pass (mx1.freebsd.org: domain of sobomax@sippysoft.com designates 209.85.219.179 as permitted sender) smtp.mailfrom=sobomax@sippysoft.com X-Spamd-Result: default: False [-2.89 / 15.00]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; NEURAL_HAM_SHORT(-0.99)[-0.987]; FORGED_SENDER(0.30)[sobomax@freebsd.org,sobomax@sippysoft.com]; R_SPF_ALLOW(-0.20)[+ip4:209.85.128.0/17]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; MIME_BASE64_TEXT(0.10)[]; R_DKIM_NA(0.00)[]; RCVD_IN_DNSWL_NONE(0.00)[209.85.219.179:from]; RWL_MAILSPIKE_POSSIBLE(0.00)[209.85.219.179:from]; ASN(0.00)[asn:15169, ipnet:209.85.128.0/17, country:US]; MLMMJ_DEST(0.00)[dev-commits-src-main@freebsd.org]; MIME_TRACE(0.00)[0:+,1:+,2:~]; RCVD_TLS_LAST(0.00)[]; TO_MATCH_ENVRCPT_SOME(0.00)[]; DMARC_NA(0.00)[freebsd.org]; FREEFALL_USER(0.00)[sobomax]; ARC_NA(0.00)[]; FROM_NEQ_ENVFROM(0.00)[sobomax@freebsd.org,sobomax@sippysoft.com]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; RCPT_COUNT_THREE(0.00)[4]; PREVIOUSLY_DELIVERED(0.00)[dev-commits-src-main@freebsd.org]; RCVD_COUNT_TWO(0.00)[2] X-ThisMailContainsUnwantedMimeParts: N --000000000000f7ae8605ea4ece83 Content-Type: text/plain; charset="UTF-8" Alan, Not sure, like some special /dev node that you can write your request to and get all info from in one or few syscalls? Source code for the /dev/geom.ctl might be a good start, as it is likely to be solving somewhat similar problems. -Max On Wed, Sep 28, 2022 at 9:33 AM Alan Somers wrote: > I don't think a different interface would necessarily fix all > consistency problems, because there are probably additional > consistency problems within ZFS itself. The ZFS stats just weren't > designed to provide a consistent view, like "zpool status". But a > different interface certainly could be much faster; sysctl is slow. > Do you have any good ideas for how to easily create such an alternate > interface? > > On Wed, Sep 28, 2022 at 10:19 AM Maxim Sobolev > wrote: > > > > This also brings a question as to whether sysctl is the right interface > to pull this data from the kernel in the first place? From my somewhat > ignorant look this approach is likely to be poised with all sorts of race > conditions, such so if configuration changes while you are pulling it out > you'd get some inconsistent view that is not here not there. Wouldn't it be > easier to use some other mechanism to pull configuration of all 1,000 > datasets as one blob in one or few system calls? Like read(2) from > /dev/zfsstats or something like that? Then you can iterate over it as much > as you need in userland. > > > > -Max > > > > On Tue, Sep 27, 2022, 3:04 AM Alan Somers wrote: > >> > >> The branch main has been updated by asomers: > >> > >> URL: > https://cgit.FreeBSD.org/src/commit/?id=d3f96f661050e9bd21fe29931992a8b9e67ff189 > >> > >> commit d3f96f661050e9bd21fe29931992a8b9e67ff189 > >> Author: Alan Somers > >> AuthorDate: 2022-09-07 14:12:49 +0000 > >> Commit: Alan Somers > >> CommitDate: 2022-09-27 00:03:34 +0000 > >> > >> Fix O(n^2) behavior in sysctl > >> > >> Sysctl OIDs were internally stored in linked lists, triggering > O(n^2) > >> behavior when userland iterates over many of them. The slowdown is > >> noticeable for MIBs that have > 100 children (for example, > vm.uma). But > >> it's unignorable for kstat.zfs when a pool has > 1000 datasets. > >> > >> Convert the linked lists into RB trees. This produces a ~25x > speedup > >> for listing kstat.zfs with 4100 datasets, and no measurable penalty > for > >> small dataset counts. > >> > >> Bump __FreeBSD_version for the KPI change. > >> > >> Sponsored by: Axcient > >> Reviewed by: mjg > >> Differential Revision: https://reviews.freebsd.org/D36500 > >> --- > >> sys/compat/linuxkpi/common/include/linux/sysfs.h | 2 +- > >> sys/kern/kern_sysctl.c | 149 > +++++++++++------------ > >> sys/kern/vfs_init.c | 2 +- > >> sys/sys/param.h | 2 +- > >> sys/sys/sysctl.h | 31 ++++- > >> 5 files changed, 99 insertions(+), 87 deletions(-) > >> > >> diff --git a/sys/compat/linuxkpi/common/include/linux/sysfs.h > b/sys/compat/linuxkpi/common/include/linux/sysfs.h > >> index 0b6b479d9362..881a72e62ed9 100644 > >> --- a/sys/compat/linuxkpi/common/include/linux/sysfs.h > >> +++ b/sys/compat/linuxkpi/common/include/linux/sysfs.h > >> @@ -246,7 +246,7 @@ sysfs_unmerge_group(struct kobject *kobj, const > struct attribute_group *grp) > >> struct attribute **attr; > >> struct sysctl_oid *oidp; > >> > >> - SLIST_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp), oid_link) { > >> + RB_FOREACH(oidp, sysctl_oid_list, SYSCTL_CHILDREN(kobj->oidp)) { > >> if (strcmp(oidp->oid_name, grp->name) != 0) > >> continue; > >> for (attr = grp->attrs; *attr != NULL; attr++) { > >> diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c > >> index 9bc595f111cc..e1cd6ea4bd61 100644 > >> --- a/sys/kern/kern_sysctl.c > >> +++ b/sys/kern/kern_sysctl.c > >> @@ -84,6 +84,8 @@ static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl > internal magic"); > >> static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids"); > >> static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output > buffer"); > >> > >> +RB_GENERATE(sysctl_oid_list, sysctl_oid, oid_link, cmp_sysctl_oid); > >> + > >> /* > >> * The sysctllock protects the MIB tree. It also protects sysctl > >> * contexts used with dynamic sysctls. The sysctl_register_oid() and > >> @@ -120,7 +122,7 @@ static struct sx sysctlstringlock; > >> static int sysctl_root(SYSCTL_HANDLER_ARGS); > >> > >> /* Root list */ > >> -struct sysctl_oid_list sysctl__children = > SLIST_HEAD_INITIALIZER(&sysctl__children); > >> +struct sysctl_oid_list sysctl__children = > RB_INITIALIZER(&sysctl__children); > >> > >> static char* sysctl_escape_name(const char*); > >> static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int > del, > >> @@ -134,7 +136,7 @@ sysctl_find_oidname(const char *name, struct > sysctl_oid_list *list) > >> struct sysctl_oid *oidp; > >> > >> SYSCTL_ASSERT_LOCKED(); > >> - SLIST_FOREACH(oidp, list, oid_link) { > >> + RB_FOREACH(oidp, sysctl_oid_list, list) { > >> if (strcmp(oidp->oid_name, name) == 0) { > >> return (oidp); > >> } > >> @@ -356,11 +358,14 @@ sysctl_search_oid(struct sysctl_oid **nodes, > struct sysctl_oid *needle) > >> indx = 0; > >> while (indx < CTL_MAXNAME && indx >= 0) { > >> if (nodes[indx] == NULL && indx == 0) > >> - nodes[indx] = SLIST_FIRST(&sysctl__children); > >> + nodes[indx] = RB_MIN(sysctl_oid_list, > >> + &sysctl__children); > >> else if (nodes[indx] == NULL) > >> - nodes[indx] = SLIST_FIRST(&nodes[indx - > 1]->oid_children); > >> + nodes[indx] = RB_MIN(sysctl_oid_list, > >> + &nodes[indx - 1]->oid_children); > >> else > >> - nodes[indx] = SLIST_NEXT(nodes[indx], oid_link); > >> + nodes[indx] = RB_NEXT(sysctl_oid_list, > >> + &nodes[indx - 1]->oid_children, > nodes[indx]); > >> > >> if (nodes[indx] == needle) > >> return (indx + 1); > >> @@ -425,8 +430,7 @@ void > >> sysctl_register_oid(struct sysctl_oid *oidp) > >> { > >> struct sysctl_oid_list *parent = oidp->oid_parent; > >> - struct sysctl_oid *p; > >> - struct sysctl_oid *q; > >> + struct sysctl_oid *p, key; > >> int oid_number; > >> int timeout = 2; > >> > >> @@ -476,25 +480,21 @@ sysctl_register_oid(struct sysctl_oid *oidp) > >> * Insert the OID into the parent's list sorted by OID number. > >> */ > >> retry: > >> - q = NULL; > >> - SLIST_FOREACH(p, parent, oid_link) { > >> - /* check if the current OID number is in use */ > >> - if (oid_number == p->oid_number) { > >> - /* get the next valid OID number */ > >> - if (oid_number < CTL_AUTO_START || > >> - oid_number == 0x7fffffff) { > >> - /* wraparound - restart */ > >> - oid_number = CTL_AUTO_START; > >> - /* don't loop forever */ > >> - if (!timeout--) > >> - panic("sysctl: Out of OID > numbers\n"); > >> - goto retry; > >> - } else { > >> - oid_number++; > >> - } > >> - } else if (oid_number < p->oid_number) > >> - break; > >> - q = p; > >> + key.oid_number = oid_number; > >> + p = RB_FIND(sysctl_oid_list, parent, &key); > >> + if (p) { > >> + /* get the next valid OID number */ > >> + if (oid_number < CTL_AUTO_START || > >> + oid_number == 0x7fffffff) { > >> + /* wraparound - restart */ > >> + oid_number = CTL_AUTO_START; > >> + /* don't loop forever */ > >> + if (!timeout--) > >> + panic("sysctl: Out of OID numbers\n"); > >> + goto retry; > >> + } else { > >> + oid_number++; > >> + } > >> } > >> /* check for non-auto OID number collision */ > >> if (oidp->oid_number >= 0 && oidp->oid_number < CTL_AUTO_START > && > >> @@ -504,10 +504,7 @@ retry: > >> } > >> /* update the OID number, if any */ > >> oidp->oid_number = oid_number; > >> - if (q != NULL) > >> - SLIST_INSERT_AFTER(q, oidp, oid_link); > >> - else > >> - SLIST_INSERT_HEAD(parent, oidp, oid_link); > >> + RB_INSERT(sysctl_oid_list, parent, oidp); > >> > >> if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE && > >> #ifdef VIMAGE > >> @@ -556,7 +553,6 @@ sysctl_enable_oid(struct sysctl_oid *oidp) > >> void > >> sysctl_unregister_oid(struct sysctl_oid *oidp) > >> { > >> - struct sysctl_oid *p; > >> int error; > >> > >> SYSCTL_ASSERT_WLOCKED(); > >> @@ -564,14 +560,8 @@ sysctl_unregister_oid(struct sysctl_oid *oidp) > >> error = EINVAL; > >> } else { > >> error = ENOENT; > >> - SLIST_FOREACH(p, oidp->oid_parent, oid_link) { > >> - if (p == oidp) { > >> - SLIST_REMOVE(oidp->oid_parent, oidp, > >> - sysctl_oid, oid_link); > >> - error = 0; > >> - break; > >> - } > >> - } > >> + if (RB_REMOVE(sysctl_oid_list, oidp->oid_parent, oidp)) > >> + error = 0; > >> } > >> > >> /* > >> @@ -732,17 +722,14 @@ int > >> sysctl_remove_name(struct sysctl_oid *parent, const char *name, > >> int del, int recurse) > >> { > >> - struct sysctl_oid *p, *tmp; > >> + struct sysctl_oid *p; > >> int error; > >> > >> error = ENOENT; > >> SYSCTL_WLOCK(); > >> - SLIST_FOREACH_SAFE(p, SYSCTL_CHILDREN(parent), oid_link, tmp) { > >> - if (strcmp(p->oid_name, name) == 0) { > >> - error = sysctl_remove_oid_locked(p, del, > recurse); > >> - break; > >> - } > >> - } > >> + p = sysctl_find_oidname(name, &parent->oid_children); > >> + if (p) > >> + error = sysctl_remove_oid_locked(p, del, recurse); > >> SYSCTL_WUNLOCK(); > >> > >> return (error); > >> @@ -811,14 +798,16 @@ sysctl_remove_oid_locked(struct sysctl_oid *oidp, > int del, int recurse) > >> */ > >> if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { > >> if (oidp->oid_refcnt == 1) { > >> - SLIST_FOREACH_SAFE(p, > >> - SYSCTL_CHILDREN(oidp), oid_link, tmp) { > >> + for(p = RB_MIN(sysctl_oid_list, > &oidp->oid_children); > >> + p != NULL; p = tmp) { > >> if (!recurse) { > >> printf("Warning: failed attempt > to " > >> "remove oid %s with child > %s\n", > >> oidp->oid_name, > p->oid_name); > >> return (ENOTEMPTY); > >> } > >> + tmp = RB_NEXT(sysctl_oid_list, > >> + &oidp->oid_children, p); > >> error = sysctl_remove_oid_locked(p, del, > >> recurse); > >> if (error) > >> @@ -895,7 +884,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, > struct sysctl_oid_list *parent, > >> } > >> oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID, > M_WAITOK|M_ZERO); > >> oidp->oid_parent = parent; > >> - SLIST_INIT(&oidp->oid_children); > >> + RB_INIT(&oidp->oid_children); > >> oidp->oid_number = number; > >> oidp->oid_refcnt = 1; > >> oidp->oid_name = escaped; > >> @@ -1016,7 +1005,7 @@ sysctl_sysctl_debug_dump_node(struct > sysctl_oid_list *l, int i) > >> struct sysctl_oid *oidp; > >> > >> SYSCTL_ASSERT_LOCKED(); > >> - SLIST_FOREACH(oidp, l, oid_link) { > >> + RB_FOREACH(oidp, sysctl_oid_list, l) { > >> for (k=0; k >> printf(" "); > >> > >> @@ -1081,7 +1070,7 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) > >> int *name = (int *) arg1; > >> u_int namelen = arg2; > >> int error; > >> - struct sysctl_oid *oid; > >> + struct sysctl_oid *oid, key; > >> struct sysctl_oid_list *lsp = &sysctl__children, *lsp2; > >> struct rm_priotracker tracker; > >> char buf[10]; > >> @@ -1105,10 +1094,9 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) > >> continue; > >> } > >> lsp2 = NULL; > >> - SLIST_FOREACH(oid, lsp, oid_link) { > >> - if (oid->oid_number != *name) > >> - continue; > >> - > >> + key.oid_number = *name; > >> + oid = RB_FIND(sysctl_oid_list, lsp, &key); > >> + if (oid) { > >> if (req->oldidx) > >> error = SYSCTL_OUT(req, ".", 1); > >> if (!error) > >> @@ -1120,14 +1108,9 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) > >> namelen--; > >> name++; > >> > >> - if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE) > >> - break; > >> - > >> - if (oid->oid_handler) > >> - break; > >> - > >> - lsp2 = SYSCTL_CHILDREN(oid); > >> - break; > >> + if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE && > >> + !oid->oid_handler) > >> + lsp2 = SYSCTL_CHILDREN(oid); > >> } > >> lsp = lsp2; > >> } > >> @@ -1239,13 +1222,25 @@ static bool > >> sysctl_sysctl_next_action(struct sysctl_oid_list *lsp, int *name, > u_int namelen, > >> int *next, int *len, int level, bool honor_skip) > >> { > >> - struct sysctl_oid *oidp; > >> + struct sysctl_oid_list *next_lsp; > >> + struct sysctl_oid *oidp = NULL, key; > >> bool success = false; > >> enum sysctl_iter_action action; > >> > >> SYSCTL_ASSERT_LOCKED(); > >> - SLIST_FOREACH(oidp, lsp, oid_link) { > >> - action = sysctl_sysctl_next_node(oidp, name, namelen, > honor_skip); > >> + /* > >> + * Start the search at the requested oid. But if not found, > then scan > >> + * through all children. > >> + */ > >> + if (namelen > 0) { > >> + key.oid_number = *name; > >> + oidp = RB_FIND(sysctl_oid_list, lsp, &key); > >> + } > >> + if (!oidp) > >> + oidp = RB_MIN(sysctl_oid_list, lsp); > >> + for(; oidp != NULL; oidp = RB_NEXT(sysctl_oid_list, lsp, oidp)) > { > >> + action = sysctl_sysctl_next_node(oidp, name, namelen, > >> + honor_skip); > >> if (action == ITER_SIBLINGS) > >> continue; > >> if (action == ITER_FOUND) { > >> @@ -1254,13 +1249,13 @@ sysctl_sysctl_next_action(struct > sysctl_oid_list *lsp, int *name, u_int namelen, > >> } > >> KASSERT((action== ITER_CHILDREN), > ("ret(%d)!=ITER_CHILDREN", action)); > >> > >> - lsp = SYSCTL_CHILDREN(oidp); > >> + next_lsp = SYSCTL_CHILDREN(oidp); > >> if (namelen == 0) { > >> - success = sysctl_sysctl_next_action(lsp, NULL, > 0, > >> + success = sysctl_sysctl_next_action(next_lsp, > NULL, 0, > >> next + 1, len, level + 1, honor_skip); > >> } else { > >> - success = sysctl_sysctl_next_action(lsp, name + > 1, namelen - 1, > >> - next + 1, len, level + 1, honor_skip); > >> + success = sysctl_sysctl_next_action(next_lsp, > name + 1, > >> + namelen - 1, next + 1, len, level + 1, > honor_skip); > >> if (!success) { > >> > >> /* > >> @@ -1332,13 +1327,12 @@ name2oid(char *name, int *oid, int *len, struct > sysctl_oid **oidpp) > >> for (*len = 0; *len < CTL_MAXNAME;) { > >> p = strsep(&name, "."); > >> > >> - oidp = SLIST_FIRST(lsp); > >> - for (;; oidp = SLIST_NEXT(oidp, oid_link)) { > >> - if (oidp == NULL) > >> - return (ENOENT); > >> + RB_FOREACH(oidp, sysctl_oid_list, lsp) { > >> if (strcmp(p, oidp->oid_name) == 0) > >> break; > >> } > >> + if (oidp == NULL) > >> + return (ENOENT); > >> *oid++ = oidp->oid_number; > >> (*len)++; > >> > >> @@ -2162,16 +2156,15 @@ sysctl_find_oid(int *name, u_int namelen, > struct sysctl_oid **noid, > >> { > >> struct sysctl_oid_list *lsp; > >> struct sysctl_oid *oid; > >> + struct sysctl_oid key; > >> int indx; > >> > >> SYSCTL_ASSERT_LOCKED(); > >> lsp = &sysctl__children; > >> indx = 0; > >> while (indx < CTL_MAXNAME) { > >> - SLIST_FOREACH(oid, lsp, oid_link) { > >> - if (oid->oid_number == name[indx]) > >> - break; > >> - } > >> + key.oid_number = name[indx]; > >> + oid = RB_FIND(sysctl_oid_list, lsp, &key); > >> if (oid == NULL) > >> return (ENOENT); > >> > >> diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c > >> index 6572a8e362c2..6e2e78aaf597 100644 > >> --- a/sys/kern/vfs_init.c > >> +++ b/sys/kern/vfs_init.c > >> @@ -525,7 +525,7 @@ vfs_register(struct vfsconf *vfc) > >> * number. > >> */ > >> sysctl_wlock(); > >> - SLIST_FOREACH(oidp, SYSCTL_CHILDREN(&sysctl___vfs), oid_link) { > >> + RB_FOREACH(oidp, sysctl_oid_list, > SYSCTL_CHILDREN(&sysctl___vfs)) { > >> if (strcmp(oidp->oid_name, vfc->vfc_name) == 0) { > >> sysctl_unregister_oid(oidp); > >> oidp->oid_number = vfc->vfc_typenum; > >> diff --git a/sys/sys/param.h b/sys/sys/param.h > >> index f875d839d41f..3f5da06ef951 100644 > >> --- a/sys/sys/param.h > >> +++ b/sys/sys/param.h > >> @@ -76,7 +76,7 @@ > >> * cannot include sys/param.h and should only be updated here. > >> */ > >> #undef __FreeBSD_version > >> -#define __FreeBSD_version 1400070 > >> +#define __FreeBSD_version 1400071 > >> > >> /* > >> * __FreeBSD_kernel__ indicates that this system uses the kernel of > FreeBSD, > >> diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h > >> index 451d83bbe125..3bd77cf87243 100644 > >> --- a/sys/sys/sysctl.h > >> +++ b/sys/sys/sysctl.h > >> @@ -39,7 +39,8 @@ > >> #define _SYS_SYSCTL_H_ > >> > >> #ifdef _KERNEL > >> -#include > >> +#include > >> +#include > >> #endif > >> > >> /* > >> @@ -173,20 +174,25 @@ struct sysctl_req { > >> int flags; > >> }; > >> > >> -SLIST_HEAD(sysctl_oid_list, sysctl_oid); > >> +struct sysctl_oid; > >> + > >> +/* RB Tree handling */ > >> +RB_HEAD(sysctl_oid_list, sysctl_oid); > >> > >> /* > >> * This describes one "oid" in the MIB tree. Potentially more nodes > can > >> * be hidden behind it, expanded by the handler. > >> */ > >> struct sysctl_oid { > >> - struct sysctl_oid_list oid_children; > >> - struct sysctl_oid_list *oid_parent; > >> - SLIST_ENTRY(sysctl_oid) oid_link; > >> + struct sysctl_oid_list oid_children; > >> + struct sysctl_oid_list* oid_parent; > >> + RB_ENTRY(sysctl_oid) oid_link; > >> + /* Sort key for all siblings, and lookup key for userland */ > >> int oid_number; > >> u_int oid_kind; > >> void *oid_arg1; > >> intmax_t oid_arg2; > >> + /* Must be unique amongst all siblings. */ > >> const char *oid_name; > >> int (*oid_handler)(SYSCTL_HANDLER_ARGS); > >> const char *oid_fmt; > >> @@ -196,6 +202,19 @@ struct sysctl_oid { > >> const char *oid_label; > >> }; > >> > >> +static inline int > >> +cmp_sysctl_oid(struct sysctl_oid *a, struct sysctl_oid *b) > >> +{ > >> + if (a->oid_number > b->oid_number) > >> + return (1); > >> + else if (a->oid_number < b->oid_number) > >> + return (-1); > >> + else > >> + return (0); > >> +} > >> + > >> +RB_PROTOTYPE(sysctl_oid_list, sysctl_oid, oid_link, cmp_sysctl_oid); > >> + > >> #define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l) > >> #define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l) > >> #define SYSCTL_OUT_STR(r, p) (r->oldfunc)(r, p, strlen(p) + > 1) > >> @@ -275,7 +294,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); > >> #define SYSCTL_OID_RAW(id, parent_child_head, nbr, name, kind, > a1, a2, handler, fmt, descr, label) \ > >> struct sysctl_oid id = { > \ > >> .oid_parent = (parent_child_head), > \ > >> - .oid_children = > SLIST_HEAD_INITIALIZER(&id.oid_children), \ > >> + .oid_children = RB_INITIALIZER(&id.oid_children), \ > >> .oid_number = (nbr), > \ > >> .oid_kind = (kind), > \ > >> .oid_arg1 = (a1), > \ > >> > > --000000000000f7ae8605ea4ece83 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+QWxhbiw8ZGl2Pjxicj48L2Rpdj48ZGl2Pk5vdCBzdXJlLCBsaWtlIHNv bWUgc3BlY2lhbCAvZGV2IG5vZGUgdGhhdCB5b3UgY2FuIHdyaXRlIHlvdXIgcmVxdWVzdCB0byBh bmQgZ2V0IGFsbCBpbmZvIGZyb20gaW4gb25lIG9yIGZldyBzeXNjYWxscz8gU291cmNlIGNvZGUg Zm9yIHRoZcKgL2Rldi9nZW9tLmN0bCBtaWdodCBiZSBhIGdvb2Qgc3RhcnQsIGFzIGl0IGlzIGxp a2VseSB0byBiZSBzb2x2aW5nIHNvbWV3aGF0IHNpbWlsYXIgcHJvYmxlbXMuPGRpdj48YnI+PC9k aXY+PGRpdj4tTWF4PC9kaXY+PC9kaXY+PC9kaXY+PGJyPjxkaXYgY2xhc3M9ImdtYWlsX3F1b3Rl Ij48ZGl2IGRpcj0ibHRyIiBjbGFzcz0iZ21haWxfYXR0ciI+T24gV2VkLCBTZXAgMjgsIDIwMjIg YXQgOTozMyBBTSBBbGFuIFNvbWVycyAmbHQ7PGEgaHJlZj0ibWFpbHRvOmFzb21lcnNAZnJlZWJz ZC5vcmciPmFzb21lcnNAZnJlZWJzZC5vcmc8L2E+Jmd0OyB3cm90ZTo8YnI+PC9kaXY+PGJsb2Nr cXVvdGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2luOjBweCAwcHggMHB4IDAuOGV4 O2JvcmRlci1sZWZ0OjFweCBzb2xpZCByZ2IoMjA0LDIwNCwyMDQpO3BhZGRpbmctbGVmdDoxZXgi PkkgZG9uJiMzOTt0IHRoaW5rIGEgZGlmZmVyZW50IGludGVyZmFjZSB3b3VsZCBuZWNlc3Nhcmls eSBmaXggYWxsPGJyPg0KY29uc2lzdGVuY3kgcHJvYmxlbXMsIGJlY2F1c2UgdGhlcmUgYXJlIHBy b2JhYmx5IGFkZGl0aW9uYWw8YnI+DQpjb25zaXN0ZW5jeSBwcm9ibGVtcyB3aXRoaW4gWkZTIGl0 c2VsZi7CoCBUaGUgWkZTIHN0YXRzIGp1c3Qgd2VyZW4mIzM5O3Q8YnI+DQpkZXNpZ25lZCB0byBw cm92aWRlIGEgY29uc2lzdGVudCB2aWV3LCBsaWtlICZxdW90O3pwb29sIHN0YXR1cyZxdW90Oy7C oCBCdXQgYTxicj4NCmRpZmZlcmVudCBpbnRlcmZhY2UgY2VydGFpbmx5IGNvdWxkIGJlIG11Y2gg ZmFzdGVyOyBzeXNjdGwgaXMgc2xvdy48YnI+DQpEbyB5b3UgaGF2ZSBhbnkgZ29vZCBpZGVhcyBm b3IgaG93IHRvIGVhc2lseSBjcmVhdGUgc3VjaCBhbiBhbHRlcm5hdGU8YnI+DQppbnRlcmZhY2U/ PGJyPg0KPGJyPg0KT24gV2VkLCBTZXAgMjgsIDIwMjIgYXQgMTA6MTkgQU0gTWF4aW0gU29ib2xl diAmbHQ7PGEgaHJlZj0ibWFpbHRvOnNvYm9tYXhAZnJlZWJzZC5vcmciIHRhcmdldD0iX2JsYW5r Ij5zb2JvbWF4QGZyZWVic2Qub3JnPC9hPiZndDsgd3JvdGU6PGJyPg0KJmd0Ozxicj4NCiZndDsg VGhpcyBhbHNvIGJyaW5ncyBhIHF1ZXN0aW9uIGFzIHRvIHdoZXRoZXIgc3lzY3RsIGlzIHRoZSBy aWdodCBpbnRlcmZhY2UgdG8gcHVsbCB0aGlzIGRhdGEgZnJvbSB0aGUga2VybmVsIGluIHRoZSBm aXJzdCBwbGFjZT8gRnJvbSBteSBzb21ld2hhdCBpZ25vcmFudCBsb29rIHRoaXMgYXBwcm9hY2gg aXMgbGlrZWx5IHRvIGJlIHBvaXNlZCB3aXRoIGFsbCBzb3J0cyBvZiByYWNlIGNvbmRpdGlvbnMs IHN1Y2ggc28gaWYgY29uZmlndXJhdGlvbiBjaGFuZ2VzIHdoaWxlIHlvdSBhcmUgcHVsbGluZyBp dCBvdXQgeW91JiMzOTtkIGdldCBzb21lIGluY29uc2lzdGVudCB2aWV3IHRoYXQgaXMgbm90IGhl cmUgbm90IHRoZXJlLiBXb3VsZG4mIzM5O3QgaXQgYmUgZWFzaWVyIHRvIHVzZSBzb21lIG90aGVy IG1lY2hhbmlzbSB0byBwdWxsIGNvbmZpZ3VyYXRpb24gb2YgYWxsIDEsMDAwIGRhdGFzZXRzIGFz IG9uZSBibG9iIGluIG9uZSBvciBmZXcgc3lzdGVtIGNhbGxzPyBMaWtlIHJlYWQoMikgZnJvbSAv ZGV2L3pmc3N0YXRzIG9yIHNvbWV0aGluZyBsaWtlIHRoYXQ/IFRoZW4geW91IGNhbiBpdGVyYXRl IG92ZXIgaXQgYXMgbXVjaCBhcyB5b3UgbmVlZCBpbiB1c2VybGFuZC48YnI+DQomZ3Q7PGJyPg0K Jmd0OyAtTWF4PGJyPg0KJmd0Ozxicj4NCiZndDsgT24gVHVlLCBTZXAgMjcsIDIwMjIsIDM6MDQg QU0gQWxhbiBTb21lcnMgJmx0OzxhIGhyZWY9Im1haWx0bzphc29tZXJzQGZyZWVic2Qub3JnIiB0 YXJnZXQ9Il9ibGFuayI+YXNvbWVyc0BmcmVlYnNkLm9yZzwvYT4mZ3Q7IHdyb3RlOjxicj4NCiZn dDsmZ3Q7PGJyPg0KJmd0OyZndDsgVGhlIGJyYW5jaCBtYWluIGhhcyBiZWVuIHVwZGF0ZWQgYnkg YXNvbWVyczo8YnI+DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7IFVSTDogPGEgaHJlZj0iaHR0cHM6 Ly9jZ2l0LkZyZWVCU0Qub3JnL3NyYy9jb21taXQvP2lkPWQzZjk2ZjY2MTA1MGU5YmQyMWZlMjk5 MzE5OTJhOGI5ZTY3ZmYxODkiIHJlbD0ibm9yZWZlcnJlciIgdGFyZ2V0PSJfYmxhbmsiPmh0dHBz Oi8vY2dpdC5GcmVlQlNELm9yZy9zcmMvY29tbWl0Lz9pZD1kM2Y5NmY2NjEwNTBlOWJkMjFmZTI5 OTMxOTkyYThiOWU2N2ZmMTg5PC9hPjxicj4NCiZndDsmZ3Q7PGJyPg0KJmd0OyZndDsgY29tbWl0 IGQzZjk2ZjY2MTA1MGU5YmQyMWZlMjk5MzE5OTJhOGI5ZTY3ZmYxODk8YnI+DQomZ3Q7Jmd0OyBB dXRob3I6wqAgwqAgwqBBbGFuIFNvbWVycyAmbHQ7YXNvbWVyc0BGcmVlQlNELm9yZyZndDs8YnI+ DQomZ3Q7Jmd0OyBBdXRob3JEYXRlOiAyMDIyLTA5LTA3IDE0OjEyOjQ5ICswMDAwPGJyPg0KJmd0 OyZndDsgQ29tbWl0OsKgIMKgIMKgQWxhbiBTb21lcnMgJmx0O2Fzb21lcnNARnJlZUJTRC5vcmcm Z3Q7PGJyPg0KJmd0OyZndDsgQ29tbWl0RGF0ZTogMjAyMi0wOS0yNyAwMDowMzozNCArMDAwMDxi cj4NCiZndDsmZ3Q7PGJyPg0KJmd0OyZndDvCoCDCoCDCoEZpeCBPKG5eMikgYmVoYXZpb3IgaW4g c3lzY3RsPGJyPg0KJmd0OyZndDs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgU3lzY3RsIE9JRHMgd2Vy ZSBpbnRlcm5hbGx5IHN0b3JlZCBpbiBsaW5rZWQgbGlzdHMsIHRyaWdnZXJpbmcgTyhuXjIpPGJy Pg0KJmd0OyZndDvCoCDCoCDCoGJlaGF2aW9yIHdoZW4gdXNlcmxhbmQgaXRlcmF0ZXMgb3ZlciBt YW55IG9mIHRoZW0uwqAgVGhlIHNsb3dkb3duIGlzPGJyPg0KJmd0OyZndDvCoCDCoCDCoG5vdGlj ZWFibGUgZm9yIE1JQnMgdGhhdCBoYXZlICZndDsgMTAwIGNoaWxkcmVuIChmb3IgZXhhbXBsZSwg dm0udW1hKS7CoCBCdXQ8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgaXQmIzM5O3MgdW5pZ25vcmFibGUg Zm9yIGtzdGF0LnpmcyB3aGVuIGEgcG9vbCBoYXMgJmd0OyAxMDAwIGRhdGFzZXRzLjxicj4NCiZn dDsmZ3Q7PGJyPg0KJmd0OyZndDvCoCDCoCDCoENvbnZlcnQgdGhlIGxpbmtlZCBsaXN0cyBpbnRv IFJCIHRyZWVzLsKgIFRoaXMgcHJvZHVjZXMgYSB+MjV4IHNwZWVkdXA8YnI+DQomZ3Q7Jmd0O8Kg IMKgIMKgZm9yIGxpc3Rpbmcga3N0YXQuemZzIHdpdGggNDEwMCBkYXRhc2V0cywgYW5kIG5vIG1l YXN1cmFibGUgcGVuYWx0eSBmb3I8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgc21hbGwgZGF0YXNldCBj b3VudHMuPGJyPg0KJmd0OyZndDs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgQnVtcCBfX0ZyZWVCU0Rf dmVyc2lvbiBmb3IgdGhlIEtQSSBjaGFuZ2UuPGJyPg0KJmd0OyZndDs8YnI+DQomZ3Q7Jmd0O8Kg IMKgIMKgU3BvbnNvcmVkIGJ5OsKgIMKgQXhjaWVudDxicj4NCiZndDsmZ3Q7wqAgwqAgwqBSZXZp ZXdlZCBieTrCoCDCoCBtamc8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgRGlmZmVyZW50aWFsIFJldmlz aW9uOiA8YSBocmVmPSJodHRwczovL3Jldmlld3MuZnJlZWJzZC5vcmcvRDM2NTAwIiByZWw9Im5v cmVmZXJyZXIiIHRhcmdldD0iX2JsYW5rIj5odHRwczovL3Jldmlld3MuZnJlZWJzZC5vcmcvRDM2 NTAwPC9hPjxicj4NCiZndDsmZ3Q7IC0tLTxicj4NCiZndDsmZ3Q7wqAgc3lzL2NvbXBhdC9saW51 eGtwaS9jb21tb24vaW5jbHVkZS9saW51eC9zeXNmcy5oIHzCoCDCoDIgKy08YnI+DQomZ3Q7Jmd0 O8KgIHN5cy9rZXJuL2tlcm5fc3lzY3RsLmPCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoHwgMTQ5ICsrKysrKysrKysrLS0tLS0tLS0tLS0tPGJyPg0KJmd0OyZndDvCoCBz eXMva2Vybi92ZnNfaW5pdC5jwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgfMKgIMKgMiArLTxicj4NCiZndDsmZ3Q7wqAgc3lzL3N5cy9wYXJhbS5owqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfMKgIMKgMiArLTxicj4N CiZndDsmZ3Q7wqAgc3lzL3N5cy9zeXNjdGwuaMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgfMKgIDMxICsrKystPGJyPg0KJmd0OyZndDvCoCA1IGZpbGVz IGNoYW5nZWQsIDk5IGluc2VydGlvbnMoKyksIDg3IGRlbGV0aW9ucygtKTxicj4NCiZndDsmZ3Q7 PGJyPg0KJmd0OyZndDsgZGlmZiAtLWdpdCBhL3N5cy9jb21wYXQvbGludXhrcGkvY29tbW9uL2lu Y2x1ZGUvbGludXgvc3lzZnMuaCBiL3N5cy9jb21wYXQvbGludXhrcGkvY29tbW9uL2luY2x1ZGUv bGludXgvc3lzZnMuaDxicj4NCiZndDsmZ3Q7IGluZGV4IDBiNmI0NzlkOTM2Mi4uODgxYTcyZTYy ZWQ5IDEwMDY0NDxicj4NCiZndDsmZ3Q7IC0tLSBhL3N5cy9jb21wYXQvbGludXhrcGkvY29tbW9u L2luY2x1ZGUvbGludXgvc3lzZnMuaDxicj4NCiZndDsmZ3Q7ICsrKyBiL3N5cy9jb21wYXQvbGlu dXhrcGkvY29tbW9uL2luY2x1ZGUvbGludXgvc3lzZnMuaDxicj4NCiZndDsmZ3Q7IEBAIC0yNDYs NyArMjQ2LDcgQEAgc3lzZnNfdW5tZXJnZV9ncm91cChzdHJ1Y3Qga29iamVjdCAqa29iaiwgY29u c3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCAqZ3JwKTxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAg wqBzdHJ1Y3QgYXR0cmlidXRlICoqYXR0cjs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgc3Ry dWN0IHN5c2N0bF9vaWQgKm9pZHA7PGJyPg0KJmd0OyZndDs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAg wqAgwqBTTElTVF9GT1JFQUNIKG9pZHAsIFNZU0NUTF9DSElMRFJFTihrb2JqLSZndDtvaWRwKSwg b2lkX2xpbmspIHs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqBSQl9GT1JFQUNIKG9pZHAsIHN5 c2N0bF9vaWRfbGlzdCwgU1lTQ1RMX0NISUxEUkVOKGtvYmotJmd0O29pZHApKSB7PGJyPg0KJmd0 OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChzdHJjbXAob2lkcC0mZ3Q7b2lkX25h bWUsIGdycC0mZ3Q7bmFtZSkgIT0gMCk8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgY29udGludWU7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoGZvciAoYXR0ciA9IGdycC0mZ3Q7YXR0cnM7ICphdHRyICE9IE5VTEw7IGF0dHIr Kykgezxicj4NCiZndDsmZ3Q7IGRpZmYgLS1naXQgYS9zeXMva2Vybi9rZXJuX3N5c2N0bC5jIGIv c3lzL2tlcm4va2Vybl9zeXNjdGwuYzxicj4NCiZndDsmZ3Q7IGluZGV4IDliYzU5NWYxMTFjYy4u ZTFjZDZlYTRiZDYxIDEwMDY0NDxicj4NCiZndDsmZ3Q7IC0tLSBhL3N5cy9rZXJuL2tlcm5fc3lz Y3RsLmM8YnI+DQomZ3Q7Jmd0OyArKysgYi9zeXMva2Vybi9rZXJuX3N5c2N0bC5jPGJyPg0KJmd0 OyZndDsgQEAgLTg0LDYgKzg0LDggQEAgc3RhdGljIE1BTExPQ19ERUZJTkUoTV9TWVNDVEwsICZx dW90O3N5c2N0bCZxdW90OywgJnF1b3Q7c3lzY3RsIGludGVybmFsIG1hZ2ljJnF1b3Q7KTs8YnI+ DQomZ3Q7Jmd0O8KgIHN0YXRpYyBNQUxMT0NfREVGSU5FKE1fU1lTQ1RMT0lELCAmcXVvdDtzeXNj dGxvaWQmcXVvdDssICZxdW90O3N5c2N0bCBkeW5hbWljIG9pZHMmcXVvdDspOzxicj4NCiZndDsm Z3Q7wqAgc3RhdGljIE1BTExPQ19ERUZJTkUoTV9TWVNDVExUTVAsICZxdW90O3N5c2N0bHRtcCZx dW90OywgJnF1b3Q7c3lzY3RsIHRlbXAgb3V0cHV0IGJ1ZmZlciZxdW90Oyk7PGJyPg0KJmd0OyZn dDs8YnI+DQomZ3Q7Jmd0OyArUkJfR0VORVJBVEUoc3lzY3RsX29pZF9saXN0LCBzeXNjdGxfb2lk LCBvaWRfbGluaywgY21wX3N5c2N0bF9vaWQpOzxicj4NCiZndDsmZ3Q7ICs8YnI+DQomZ3Q7Jmd0 O8KgIC8qPGJyPg0KJmd0OyZndDvCoCDCoCogVGhlIHN5c2N0bGxvY2sgcHJvdGVjdHMgdGhlIE1J QiB0cmVlLsKgIEl0IGFsc28gcHJvdGVjdHMgc3lzY3RsPGJyPg0KJmd0OyZndDvCoCDCoCogY29u dGV4dHMgdXNlZCB3aXRoIGR5bmFtaWMgc3lzY3Rscy7CoCBUaGUgc3lzY3RsX3JlZ2lzdGVyX29p ZCgpIGFuZDxicj4NCiZndDsmZ3Q7IEBAIC0xMjAsNyArMTIyLDcgQEAgc3RhdGljIHN0cnVjdCBz eCBzeXNjdGxzdHJpbmdsb2NrOzxicj4NCiZndDsmZ3Q7wqAgc3RhdGljIGludCBzeXNjdGxfcm9v dChTWVNDVExfSEFORExFUl9BUkdTKTs8YnI+DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7wqAgLyog Um9vdCBsaXN0ICovPGJyPg0KJmd0OyZndDsgLXN0cnVjdCBzeXNjdGxfb2lkX2xpc3Qgc3lzY3Rs X19jaGlsZHJlbiA9IFNMSVNUX0hFQURfSU5JVElBTElaRVIoJmFtcDtzeXNjdGxfX2NoaWxkcmVu KTs8YnI+DQomZ3Q7Jmd0OyArc3RydWN0IHN5c2N0bF9vaWRfbGlzdCBzeXNjdGxfX2NoaWxkcmVu ID0gUkJfSU5JVElBTElaRVIoJmFtcDtzeXNjdGxfX2NoaWxkcmVuKTs8YnI+DQomZ3Q7Jmd0Ozxi cj4NCiZndDsmZ3Q7wqAgc3RhdGljIGNoYXIqwqAgwqBzeXNjdGxfZXNjYXBlX25hbWUoY29uc3Qg Y2hhciopOzxicj4NCiZndDsmZ3Q7wqAgc3RhdGljIGludMKgIMKgIMKgc3lzY3RsX3JlbW92ZV9v aWRfbG9ja2VkKHN0cnVjdCBzeXNjdGxfb2lkICpvaWRwLCBpbnQgZGVsLDxicj4NCiZndDsmZ3Q7 IEBAIC0xMzQsNyArMTM2LDcgQEAgc3lzY3RsX2ZpbmRfb2lkbmFtZShjb25zdCBjaGFyICpuYW1l LCBzdHJ1Y3Qgc3lzY3RsX29pZF9saXN0ICpsaXN0KTxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAg wqBzdHJ1Y3Qgc3lzY3RsX29pZCAqb2lkcDs8YnI+DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7wqAg wqAgwqAgwqAgwqBTWVNDVExfQVNTRVJUX0xPQ0tFRCgpOzxicj4NCiZndDsmZ3Q7IC3CoCDCoCDC oCDCoFNMSVNUX0ZPUkVBQ0gob2lkcCwgbGlzdCwgb2lkX2xpbmspIHs8YnI+DQomZ3Q7Jmd0OyAr wqAgwqAgwqAgwqBSQl9GT1JFQUNIKG9pZHAsIHN5c2N0bF9vaWRfbGlzdCwgbGlzdCkgezxicj4N CiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoc3RyY21wKG9pZHAtJmd0O29p ZF9uYW1lLCBuYW1lKSA9PSAwKSB7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoHJldHVybiAob2lkcCk7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoH08YnI+DQomZ3Q7Jmd0OyBAQCAtMzU2LDExICszNTgsMTQgQEAgc3lzY3Rs X3NlYXJjaF9vaWQoc3RydWN0IHN5c2N0bF9vaWQgKipub2Rlcywgc3RydWN0IHN5c2N0bF9vaWQg Km5lZWRsZSk8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgaW5keCA9IDA7PGJyPg0KJmd0OyZn dDvCoCDCoCDCoCDCoCDCoHdoaWxlIChpbmR4ICZsdDsgQ1RMX01BWE5BTUUgJmFtcDsmYW1wOyBp bmR4ICZndDs9IDApIHs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYg KG5vZGVzW2luZHhdID09IE5VTEwgJmFtcDsmYW1wOyBpbmR4ID09IDApPGJyPg0KJmd0OyZndDsg LcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbm9kZXNbaW5keF0gPSBTTElTVF9G SVJTVCgmYW1wO3N5c2N0bF9fY2hpbGRyZW4pOzxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoG5vZGVzW2luZHhdID0gUkJfTUlOKHN5c2N0bF9vaWRfbGlz dCw8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAmYW1wO3N5c2N0bF9fY2hpbGRyZW4pOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBlbHNlIGlmIChub2Rlc1tpbmR4XSA9PSBOVUxMKTxicj4NCiZndDsmZ3Q7IC3CoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG5vZGVzW2luZHhdID0gU0xJU1RfRklSU1Qo JmFtcDtub2Rlc1tpbmR4IC0gMV0tJmd0O29pZF9jaGlsZHJlbik7PGJyPg0KJmd0OyZndDsgK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbm9kZXNbaW5keF0gPSBSQl9NSU4oc3lz Y3RsX29pZF9saXN0LDxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCZhbXA7bm9kZXNbaW5keCAtIDFdLSZndDtvaWRfY2hpbGRyZW4pOzxicj4N CiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlbHNlPGJyPg0KJmd0OyZndDsgLcKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbm9kZXNbaW5keF0gPSBTTElTVF9ORVhU KG5vZGVzW2luZHhdLCBvaWRfbGluayk7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgbm9kZXNbaW5keF0gPSBSQl9ORVhUKHN5c2N0bF9vaWRfbGlzdCw8 YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAm YW1wO25vZGVzW2luZHggLSAxXS0mZ3Q7b2lkX2NoaWxkcmVuLCBub2Rlc1tpbmR4XSk7PGJyPg0K Jmd0OyZndDs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKG5vZGVz W2luZHhdID09IG5lZWRsZSk8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgcmV0dXJuIChpbmR4ICsgMSk7PGJyPg0KJmd0OyZndDsgQEAgLTQyNSw4ICs0 MzAsNyBAQCB2b2lkPGJyPg0KJmd0OyZndDvCoCBzeXNjdGxfcmVnaXN0ZXJfb2lkKHN0cnVjdCBz eXNjdGxfb2lkICpvaWRwKTxicj4NCiZndDsmZ3Q7wqAgezxicj4NCiZndDsmZ3Q7wqAgwqAgwqAg wqAgwqBzdHJ1Y3Qgc3lzY3RsX29pZF9saXN0ICpwYXJlbnQgPSBvaWRwLSZndDtvaWRfcGFyZW50 Ozxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoHN0cnVjdCBzeXNjdGxfb2lkICpwOzxicj4NCiZn dDsmZ3Q7IC3CoCDCoCDCoCDCoHN0cnVjdCBzeXNjdGxfb2lkICpxOzxicj4NCiZndDsmZ3Q7ICvC oCDCoCDCoCDCoHN0cnVjdCBzeXNjdGxfb2lkICpwLCBrZXk7PGJyPg0KJmd0OyZndDvCoCDCoCDC oCDCoCDCoGludCBvaWRfbnVtYmVyOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBpbnQgdGlt ZW91dCA9IDI7PGJyPg0KJmd0OyZndDs8YnI+DQomZ3Q7Jmd0OyBAQCAtNDc2LDI1ICs0ODAsMjEg QEAgc3lzY3RsX3JlZ2lzdGVyX29pZChzdHJ1Y3Qgc3lzY3RsX29pZCAqb2lkcCk8YnI+DQomZ3Q7 Jmd0O8KgIMKgIMKgIMKgIMKgICogSW5zZXJ0IHRoZSBPSUQgaW50byB0aGUgcGFyZW50JiMzOTtz IGxpc3Qgc29ydGVkIGJ5IE9JRCBudW1iZXIuPGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCAq Lzxicj4NCiZndDsmZ3Q7wqAgcmV0cnk6PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgcSA9IE5V TEw7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgU0xJU1RfRk9SRUFDSChwLCBwYXJlbnQsIG9p ZF9saW5rKSB7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogY2hlY2sg aWYgdGhlIGN1cnJlbnQgT0lEIG51bWJlciBpcyBpbiB1c2UgKi88YnI+DQomZ3Q7Jmd0OyAtwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAob2lkX251bWJlciA9PSBwLSZndDtvaWRfbnVtYmVyKSB7 PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogZ2V0 IHRoZSBuZXh0IHZhbGlkIE9JRCBudW1iZXIgKi88YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAob2lkX251bWJlciAmbHQ7IENUTF9BVVRPX1NUQVJU IHx8PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgb2lkX251bWJlciA9PSAweDdmZmZmZmZmKSB7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogd3JhcGFyb3VuZCAtIHJlc3Rh cnQgKi88YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBvaWRfbnVtYmVyID0gQ1RMX0FVVE9fU1RBUlQ7PGJyPg0KJmd0OyZndDsgLcKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogZG9uJiMzOTt0 IGxvb3AgZm9yZXZlciAqLzxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICghdGltZW91dC0tKTxicj4NCiZndDsmZ3Q7IC3CoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHBh bmljKCZxdW90O3N5c2N0bDogT3V0IG9mIE9JRCBudW1iZXJzXG4mcXVvdDspOzxicj4NCiZndDsm Z3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGdvdG8g cmV0cnk7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg fSBlbHNlIHs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBvaWRfbnVtYmVyKys7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDC oCDCoH0gZWxzZSBpZiAob2lkX251bWJlciAmbHQ7IHAtJmd0O29pZF9udW1iZXIpPGJyPg0KJmd0 OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KJmd0 OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcSA9IHA7PGJyPg0KJmd0OyZndDsgK8KgIMKg IMKgIMKga2V5Lm9pZF9udW1iZXIgPSBvaWRfbnVtYmVyOzxicj4NCiZndDsmZ3Q7ICvCoCDCoCDC oCDCoHAgPSBSQl9GSU5EKHN5c2N0bF9vaWRfbGlzdCwgcGFyZW50LCAmYW1wO2tleSk7PGJyPg0K Jmd0OyZndDsgK8KgIMKgIMKgIMKgaWYgKHApIHs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAvKiBnZXQgdGhlIG5leHQgdmFsaWQgT0lEIG51bWJlciAqLzxicj4NCiZndDsm Z3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChvaWRfbnVtYmVyICZsdDsgQ1RMX0FVVE9f U1RBUlQgfHw8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBvaWRf bnVtYmVyID09IDB4N2ZmZmZmZmYpIHs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAvKiB3cmFwYXJvdW5kIC0gcmVzdGFydCAqLzxicj4NCiZndDsmZ3Q7 ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG9pZF9udW1iZXIgPSBDVExfQVVU T19TVEFSVDs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAvKiBkb24mIzM5O3QgbG9vcCBmb3JldmVyICovPGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKCF0aW1lb3V0LS0pPGJyPg0KJmd0OyZndDsgK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcGFuaWMoJnF1b3Q7 c3lzY3RsOiBPdXQgb2YgT0lEIG51bWJlcnNcbiZxdW90Oyk7PGJyPg0KJmd0OyZndDsgK8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZ290byByZXRyeTs8YnI+DQomZ3Q7Jmd0OyAr wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9IGVsc2Ugezxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG9pZF9udW1iZXIrKzs8YnI+DQomZ3Q7Jmd0OyArwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoH08YnI+DQom Z3Q7Jmd0O8KgIMKgIMKgIMKgIMKgLyogY2hlY2sgZm9yIG5vbi1hdXRvIE9JRCBudW1iZXIgY29s bGlzaW9uICovPGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoGlmIChvaWRwLSZndDtvaWRfbnVt YmVyICZndDs9IDAgJmFtcDsmYW1wOyBvaWRwLSZndDtvaWRfbnVtYmVyICZsdDsgQ1RMX0FVVE9f U1RBUlQgJmFtcDsmYW1wOzxicj4NCiZndDsmZ3Q7IEBAIC01MDQsMTAgKzUwNCw3IEBAIHJldHJ5 Ojxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqB9PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDC oC8qIHVwZGF0ZSB0aGUgT0lEIG51bWJlciwgaWYgYW55ICovPGJyPg0KJmd0OyZndDvCoCDCoCDC oCDCoCDCoG9pZHAtJmd0O29pZF9udW1iZXIgPSBvaWRfbnVtYmVyOzxicj4NCiZndDsmZ3Q7IC3C oCDCoCDCoCDCoGlmIChxICE9IE5VTEwpPGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgU0xJU1RfSU5TRVJUX0FGVEVSKHEsIG9pZHAsIG9pZF9saW5rKTs8YnI+DQomZ3Q7Jmd0 OyAtwqAgwqAgwqAgwqBlbHNlPGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg U0xJU1RfSU5TRVJUX0hFQUQocGFyZW50LCBvaWRwLCBvaWRfbGluayk7PGJyPg0KJmd0OyZndDsg K8KgIMKgIMKgIMKgUkJfSU5TRVJUKHN5c2N0bF9vaWRfbGlzdCwgcGFyZW50LCBvaWRwKTs8YnI+ DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBpZiAoKG9pZHAtJmd0O29pZF9r aW5kICZhbXA7IENUTFRZUEUpICE9IENUTFRZUEVfTk9ERSAmYW1wOyZhbXA7PGJyPg0KJmd0OyZn dDvCoCAjaWZkZWYgVklNQUdFPGJyPg0KJmd0OyZndDsgQEAgLTU1Niw3ICs1NTMsNiBAQCBzeXNj dGxfZW5hYmxlX29pZChzdHJ1Y3Qgc3lzY3RsX29pZCAqb2lkcCk8YnI+DQomZ3Q7Jmd0O8KgIHZv aWQ8YnI+DQomZ3Q7Jmd0O8KgIHN5c2N0bF91bnJlZ2lzdGVyX29pZChzdHJ1Y3Qgc3lzY3RsX29p ZCAqb2lkcCk8YnI+DQomZ3Q7Jmd0O8KgIHs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqBzdHJ1 Y3Qgc3lzY3RsX29pZCAqcDs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgaW50IGVycm9yOzxi cj4NCiZndDsmZ3Q7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoFNZU0NUTF9BU1NFUlRfV0xP Q0tFRCgpOzxicj4NCiZndDsmZ3Q7IEBAIC01NjQsMTQgKzU2MCw4IEBAIHN5c2N0bF91bnJlZ2lz dGVyX29pZChzdHJ1Y3Qgc3lzY3RsX29pZCAqb2lkcCk8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgZXJyb3IgPSBFSU5WQUw7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDC oH0gZWxzZSB7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVycm9yID0g RU5PRU5UOzxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFNMSVNUX0ZPUkVB Q0gocCwgb2lkcC0mZ3Q7b2lkX3BhcmVudCwgb2lkX2xpbmspIHs8YnI+DQomZ3Q7Jmd0OyAtwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAocCA9PSBvaWRwKSB7PGJyPg0KJmd0 OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgU0xJ U1RfUkVNT1ZFKG9pZHAtJmd0O29pZF9wYXJlbnQsIG9pZHAsPGJyPg0KJmd0OyZndDsgLcKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3lzY3RsX29p ZCwgb2lkX2xpbmspOzxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoGVycm9yID0gMDs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQomZ3Q7Jmd0OyAt wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KJmd0OyZndDsgLcKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oGlmIChSQl9SRU1PVkUoc3lzY3RsX29pZF9saXN0LCBvaWRwLSZndDtvaWRfcGFyZW50LCBvaWRw KSk8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnJv ciA9IDA7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoH08YnI+DQomZ3Q7Jmd0Ozxicj4NCiZn dDsmZ3Q7wqAgwqAgwqAgwqAgwqAvKjxicj4NCiZndDsmZ3Q7IEBAIC03MzIsMTcgKzcyMiwxNCBA QCBpbnQ8YnI+DQomZ3Q7Jmd0O8KgIHN5c2N0bF9yZW1vdmVfbmFtZShzdHJ1Y3Qgc3lzY3RsX29p ZCAqcGFyZW50LCBjb25zdCBjaGFyICpuYW1lLDxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgaW50IGRl bCwgaW50IHJlY3Vyc2UpPGJyPg0KJmd0OyZndDvCoCB7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKg IMKgc3RydWN0IHN5c2N0bF9vaWQgKnAsICp0bXA7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKg c3RydWN0IHN5c2N0bF9vaWQgKnA7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoGludCBlcnJv cjs8YnI+DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBlcnJvciA9IEVOT0VO VDs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgU1lTQ1RMX1dMT0NLKCk7PGJyPg0KJmd0OyZn dDsgLcKgIMKgIMKgIMKgU0xJU1RfRk9SRUFDSF9TQUZFKHAsIFNZU0NUTF9DSElMRFJFTihwYXJl bnQpLCBvaWRfbGluaywgdG1wKSB7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgaWYgKHN0cmNtcChwLSZndDtvaWRfbmFtZSwgbmFtZSkgPT0gMCkgezxicj4NCiZndDsmZ3Q7 IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVycm9yID0gc3lzY3RsX3JlbW92 ZV9vaWRfbG9ja2VkKHAsIGRlbCwgcmVjdXJzZSk7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgfTxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoH08YnI+DQomZ3Q7Jmd0OyAr wqAgwqAgwqAgwqBwID0gc3lzY3RsX2ZpbmRfb2lkbmFtZShuYW1lLCAmYW1wO3BhcmVudC0mZ3Q7 b2lkX2NoaWxkcmVuKTs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqBpZiAocCk8YnI+DQomZ3Q7 Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnJvciA9IHN5c2N0bF9yZW1vdmVfb2lkX2xv Y2tlZChwLCBkZWwsIHJlY3Vyc2UpOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBTWVNDVExf V1VOTE9DSygpOzxicj4NCiZndDsmZ3Q7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoHJldHVy biAoZXJyb3IpOzxicj4NCiZndDsmZ3Q7IEBAIC04MTEsMTQgKzc5OCwxNiBAQCBzeXNjdGxfcmVt b3ZlX29pZF9sb2NrZWQoc3RydWN0IHN5c2N0bF9vaWQgKm9pZHAsIGludCBkZWwsIGludCByZWN1 cnNlKTxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgKi88YnI+DQomZ3Q7Jmd0O8KgIMKgIMKg IMKgIMKgaWYgKChvaWRwLSZndDtvaWRfa2luZCAmYW1wOyBDVExUWVBFKSA9PSBDVExUWVBFX05P REUpIHs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKG9pZHAtJmd0 O29pZF9yZWZjbnQgPT0gMSkgezxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoFNMSVNUX0ZPUkVBQ0hfU0FGRShwLDxicj4NCiZndDsmZ3Q7IC3CoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFNZU0NUTF9DSElMRFJFTihvaWRwKSwg b2lkX2xpbmssIHRtcCkgezxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoGZvcihwID0gUkJfTUlOKHN5c2N0bF9vaWRfbGlzdCwgJmFtcDtvaWRwLSZndDtv aWRfY2hpbGRyZW4pOzxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoHAgIT0gTlVMTDsgcCA9IHRtcCkgezxicj4NCiZndDsmZ3Q7wqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoIXJlY3Vyc2UpIHs8 YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgcHJpbnRmKCZxdW90O1dhcm5pbmc6IGZhaWxlZCBhdHRlbXB0IHRv ICZxdW90Ozxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtyZW1vdmUgb2lkICVzIHdpdGgg Y2hpbGQgJXNcbiZxdW90Oyw8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgb2lkcC0mZ3Q7b2lkX25h bWUsIHAtJmd0O29pZF9uYW1lKTs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0dXJuIChFTk9URU1QVFkp Ozxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqB9PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgdG1wID0gUkJfTkVYVChzeXNjdGxfb2lkX2xpc3QsPGJyPg0KJmd0OyZn dDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg JmFtcDtvaWRwLSZndDtvaWRfY2hpbGRyZW4sIHApOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnJvciA9IHN5c2N0bF9yZW1v dmVfb2lkX2xvY2tlZChwLCBkZWwsPGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJlY3Vyc2UpOzxicj4NCiZndDsmZ3Q7 wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoZXJy b3IpPGJyPg0KJmd0OyZndDsgQEAgLTg5NSw3ICs4ODQsNyBAQCBzeXNjdGxfYWRkX29pZChzdHJ1 Y3Qgc3lzY3RsX2N0eF9saXN0ICpjbGlzdCwgc3RydWN0IHN5c2N0bF9vaWRfbGlzdCAqcGFyZW50 LDxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqB9PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDC oG9pZHAgPSBtYWxsb2Moc2l6ZW9mKHN0cnVjdCBzeXNjdGxfb2lkKSwgTV9TWVNDVExPSUQsIE1f V0FJVE9LfE1fWkVSTyk7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoG9pZHAtJmd0O29pZF9w YXJlbnQgPSBwYXJlbnQ7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgU0xJU1RfSU5JVCgmYW1w O29pZHAtJmd0O29pZF9jaGlsZHJlbik7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgUkJfSU5J VCgmYW1wO29pZHAtJmd0O29pZF9jaGlsZHJlbik7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDC oG9pZHAtJmd0O29pZF9udW1iZXIgPSBudW1iZXI7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDC oG9pZHAtJmd0O29pZF9yZWZjbnQgPSAxOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBvaWRw LSZndDtvaWRfbmFtZSA9IGVzY2FwZWQ7PGJyPg0KJmd0OyZndDsgQEAgLTEwMTYsNyArMTAwNSw3 IEBAIHN5c2N0bF9zeXNjdGxfZGVidWdfZHVtcF9ub2RlKHN0cnVjdCBzeXNjdGxfb2lkX2xpc3Qg KmwsIGludCBpKTxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBzdHJ1Y3Qgc3lzY3RsX29pZCAq b2lkcDs8YnI+DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBTWVNDVExfQVNT RVJUX0xPQ0tFRCgpOzxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoFNMSVNUX0ZPUkVBQ0gob2lk cCwgbCwgb2lkX2xpbmspIHs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqBSQl9GT1JFQUNIKG9p ZHAsIHN5c2N0bF9vaWRfbGlzdCwgbCkgezxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBmb3IgKGs9MDsgayZsdDtpOyBrKyspPGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHByaW50ZigmcXVvdDsgJnF1b3Q7KTs8YnI+DQomZ3Q7 Jmd0Ozxicj4NCiZndDsmZ3Q7IEBAIC0xMDgxLDcgKzEwNzAsNyBAQCBzeXNjdGxfc3lzY3RsX25h bWUoU1lTQ1RMX0hBTkRMRVJfQVJHUyk8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgaW50ICpu YW1lID0gKGludCAqKSBhcmcxOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqB1X2ludCBuYW1l bGVuID0gYXJnMjs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgaW50IGVycm9yOzxicj4NCiZn dDsmZ3Q7IC3CoCDCoCDCoCDCoHN0cnVjdCBzeXNjdGxfb2lkICpvaWQ7PGJyPg0KJmd0OyZndDsg K8KgIMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWQgKm9pZCwga2V5Ozxicj4NCiZndDsmZ3Q7wqAg wqAgwqAgwqAgwqBzdHJ1Y3Qgc3lzY3RsX29pZF9saXN0ICpsc3AgPSAmYW1wO3N5c2N0bF9fY2hp bGRyZW4sICpsc3AyOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBzdHJ1Y3Qgcm1fcHJpb3Ry YWNrZXIgdHJhY2tlcjs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgY2hhciBidWZbMTBdOzxi cj4NCiZndDsmZ3Q7IEBAIC0xMTA1LDEwICsxMDk0LDkgQEAgc3lzY3RsX3N5c2N0bF9uYW1lKFNZ U0NUTF9IQU5ETEVSX0FSR1MpPGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoGNvbnRpbnVlOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqB9PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGxzcDIgPSBOVUxM Ozxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFNMSVNUX0ZPUkVBQ0gob2lk LCBsc3AsIG9pZF9saW5rKSB7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgaWYgKG9pZC0mZ3Q7b2lkX251bWJlciAhPSAqbmFtZSk8YnI+DQomZ3Q7Jmd0 OyAtwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjb250aW51 ZTs8YnI+DQomZ3Q7Jmd0OyAtPGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg a2V5Lm9pZF9udW1iZXIgPSAqbmFtZTs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBvaWQgPSBSQl9GSU5EKHN5c2N0bF9vaWRfbGlzdCwgbHNwLCAmYW1wO2tleSk7PGJyPg0K Jmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKG9pZCkgezxicj4NCiZndDsmZ3Q7 wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAocmVxLSZndDtvbGRpZHgp PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoGVycm9yID0gU1lTQ1RMX09VVChyZXEsICZxdW90Oy4mcXVvdDssIDEpOzxicj4NCiZn dDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoIWVycm9yKTxi cj4NCiZndDsmZ3Q7IEBAIC0xMTIwLDE0ICsxMTA4LDkgQEAgc3lzY3RsX3N5c2N0bF9uYW1lKFNZ U0NUTF9IQU5ETEVSX0FSR1MpPGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoG5hbWVsZW4tLTs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgbmFtZSsrOzxicj4NCiZndDsmZ3Q7PGJyPg0KJmd0OyZndDsgLcKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKChvaWQtJmd0O29pZF9raW5kICZh bXA7IENUTFRZUEUpICE9IENUTFRZUEVfTk9ERSk8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQomZ3Q7Jmd0OyAt PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKG9p ZC0mZ3Q7b2lkX2hhbmRsZXIpPGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KJmd0OyZndDsgLTxicj4NCiZndDsm Z3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGxzcDIgPSBTWVNDVExfQ0hJ TERSRU4ob2lkKTs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBicmVhazs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBpZiAoKG9pZC0mZ3Q7b2lkX2tpbmQgJmFtcDsgQ1RMVFlQRSkgPT0gQ1RMVFlQRV9OT0RF ICZhbXA7JmFtcDs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAhb2lkLSZndDtvaWRfaGFuZGxlcik8YnI+DQomZ3Q7Jmd0OyArwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBsc3AyID0gU1lTQ1RM X0NISUxEUkVOKG9pZCk7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08 YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbHNwID0gbHNwMjs8YnI+DQom Z3Q7Jmd0O8KgIMKgIMKgIMKgIMKgfTxicj4NCiZndDsmZ3Q7IEBAIC0xMjM5LDEzICsxMjIyLDI1 IEBAIHN0YXRpYyBib29sPGJyPg0KJmd0OyZndDvCoCBzeXNjdGxfc3lzY3RsX25leHRfYWN0aW9u KHN0cnVjdCBzeXNjdGxfb2lkX2xpc3QgKmxzcCwgaW50ICpuYW1lLCB1X2ludCBuYW1lbGVuLDxi cj4NCiZndDsmZ3Q7wqAgwqAgwqAgaW50ICpuZXh0LCBpbnQgKmxlbiwgaW50IGxldmVsLCBib29s IGhvbm9yX3NraXApPGJyPg0KJmd0OyZndDvCoCB7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKg c3RydWN0IHN5c2N0bF9vaWQgKm9pZHA7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgc3RydWN0 IHN5c2N0bF9vaWRfbGlzdCAqbmV4dF9sc3A7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgc3Ry dWN0IHN5c2N0bF9vaWQgKm9pZHAgPSBOVUxMLCBrZXk7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDC oCDCoGJvb2wgc3VjY2VzcyA9IGZhbHNlOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBlbnVt IHN5c2N0bF9pdGVyX2FjdGlvbiBhY3Rpb247PGJyPg0KJmd0OyZndDs8YnI+DQomZ3Q7Jmd0O8Kg IMKgIMKgIMKgIMKgU1lTQ1RMX0FTU0VSVF9MT0NLRUQoKTs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAg wqAgwqBTTElTVF9GT1JFQUNIKG9pZHAsIGxzcCwgb2lkX2xpbmspIHs8YnI+DQomZ3Q7Jmd0OyAt wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhY3Rpb24gPSBzeXNjdGxfc3lzY3RsX25leHRfbm9kZShv aWRwLCBuYW1lLCBuYW1lbGVuLCBob25vcl9za2lwKTs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAg wqAvKjxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCAqIFN0YXJ0IHRoZSBzZWFyY2ggYXQgdGhl IHJlcXVlc3RlZCBvaWQuwqAgQnV0IGlmIG5vdCBmb3VuZCwgdGhlbiBzY2FuPGJyPg0KJmd0OyZn dDsgK8KgIMKgIMKgIMKgICogdGhyb3VnaCBhbGwgY2hpbGRyZW4uPGJyPg0KJmd0OyZndDsgK8Kg IMKgIMKgIMKgICovPGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgaWYgKG5hbWVsZW4gJmd0OyAw KSB7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKga2V5Lm9pZF9udW1iZXIg PSAqbmFtZTs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBvaWRwID0gUkJf RklORChzeXNjdGxfb2lkX2xpc3QsIGxzcCwgJmFtcDtrZXkpOzxicj4NCiZndDsmZ3Q7ICvCoCDC oCDCoCDCoH08YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqBpZiAoIW9pZHApPGJyPg0KJmd0OyZn dDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgb2lkcCA9IFJCX01JTihzeXNjdGxfb2lkX2xpc3Qs IGxzcCk7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgZm9yKDsgb2lkcCAhPSBOVUxMOyBvaWRw ID0gUkJfTkVYVChzeXNjdGxfb2lkX2xpc3QsIGxzcCwgb2lkcCkpIHs8YnI+DQomZ3Q7Jmd0OyAr wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhY3Rpb24gPSBzeXNjdGxfc3lzY3RsX25leHRfbm9kZShv aWRwLCBuYW1lLCBuYW1lbGVuLDxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoGhvbm9yX3NraXApOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBpZiAoYWN0aW9uID09IElURVJfU0lCTElOR1MpPGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNvbnRpbnVlOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqBpZiAoYWN0aW9uID09IElURVJfRk9VTkQpIHs8YnI+DQomZ3Q7Jmd0 OyBAQCAtMTI1NCwxMyArMTI0OSwxMyBAQCBzeXNjdGxfc3lzY3RsX25leHRfYWN0aW9uKHN0cnVj dCBzeXNjdGxfb2lkX2xpc3QgKmxzcCwgaW50ICpuYW1lLCB1X2ludCBuYW1lbGVuLDxicj4NCiZn dDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoEtBU1NFUlQoKGFjdGlvbj09IElURVJfQ0hJTERSRU4pLCAoJnF1b3Q7 cmV0KCVkKSE9SVRFUl9DSElMRFJFTiZxdW90OywgYWN0aW9uKSk7PGJyPg0KJmd0OyZndDs8YnI+ DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBsc3AgPSBTWVNDVExfQ0hJTERSRU4o b2lkcCk7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbmV4dF9sc3AgPSBT WVNDVExfQ0hJTERSRU4ob2lkcCk7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoGlmIChuYW1lbGVuID09IDApIHs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqBzdWNjZXNzID0gc3lzY3RsX3N5c2N0bF9uZXh0X2FjdGlvbihsc3As IE5VTEwsIDAsPGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgc3VjY2VzcyA9IHN5c2N0bF9zeXNjdGxfbmV4dF9hY3Rpb24obmV4dF9sc3AsIE5VTEwsIDAs PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oG5leHQgKyAxLCBsZW4sIGxldmVsICsgMSwgaG9ub3Jfc2tpcCk7PGJyPg0KJmd0OyZndDvCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0gZWxzZSB7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3VjY2VzcyA9IHN5c2N0bF9zeXNjdGxfbmV4dF9hY3Rp b24obHNwLCBuYW1lICsgMSwgbmFtZWxlbiAtIDEsPGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbmV4dCArIDEsIGxlbiwgbGV2ZWwgKyAxLCBo b25vcl9za2lwKTs8YnI+DQomZ3Q7Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBzdWNjZXNzID0gc3lzY3RsX3N5c2N0bF9uZXh0X2FjdGlvbihuZXh0X2xzcCwgbmFtZSAr IDEsPGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgbmFtZWxlbiAtIDEsIG5leHQgKyAxLCBsZW4sIGxldmVsICsgMSwgaG9ub3Jfc2tpcCk7PGJy Pg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICghc3Vj Y2Vzcykgezxicj4NCiZndDsmZ3Q7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qPGJyPg0KJmd0OyZndDsgQEAgLTEzMzIsMTMg KzEzMjcsMTIgQEAgbmFtZTJvaWQoY2hhciAqbmFtZSwgaW50ICpvaWQsIGludCAqbGVuLCBzdHJ1 Y3Qgc3lzY3RsX29pZCAqKm9pZHBwKTxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBmb3IgKCps ZW4gPSAwOyAqbGVuICZsdDsgQ1RMX01BWE5BTUU7KSB7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoHAgPSBzdHJzZXAoJmFtcDtuYW1lLCAmcXVvdDsuJnF1b3Q7KTs8YnI+ DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG9pZHAgPSBT TElTVF9GSVJTVChsc3ApOzxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGZv ciAoOzsgb2lkcCA9IFNMSVNUX05FWFQob2lkcCwgb2lkX2xpbmspKSB7PGJyPg0KJmd0OyZndDsg LcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKG9pZHAgPT0gTlVMTCk8YnI+ DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqByZXR1cm4gKEVOT0VOVCk7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg UkJfRk9SRUFDSChvaWRwLCBzeXNjdGxfb2lkX2xpc3QsIGxzcCkgezxicj4NCiZndDsmZ3Q7wqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoc3RyY21wKHAsIG9pZHAtJmd0 O29pZF9uYW1lKSA9PSAwKTxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgfTxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChv aWRwID09IE5VTEwpPGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgcmV0dXJuIChFTk9FTlQpOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAqb2lkKysgPSBvaWRwLSZndDtvaWRfbnVtYmVyOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAoKmxlbikrKzs8YnI+DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7IEBA IC0yMTYyLDE2ICsyMTU2LDE1IEBAIHN5c2N0bF9maW5kX29pZChpbnQgKm5hbWUsIHVfaW50IG5h bWVsZW4sIHN0cnVjdCBzeXNjdGxfb2lkICoqbm9pZCw8YnI+DQomZ3Q7Jmd0O8KgIHs8YnI+DQom Z3Q7Jmd0O8KgIMKgIMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWRfbGlzdCAqbHNwOzxicj4NCiZn dDsmZ3Q7wqAgwqAgwqAgwqAgwqBzdHJ1Y3Qgc3lzY3RsX29pZCAqb2lkOzxicj4NCiZndDsmZ3Q7 ICvCoCDCoCDCoCDCoHN0cnVjdCBzeXNjdGxfb2lkIGtleTs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKg IMKgIMKgaW50IGluZHg7PGJyPg0KJmd0OyZndDs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKg U1lTQ1RMX0FTU0VSVF9MT0NLRUQoKTs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgbHNwID0g JmFtcDtzeXNjdGxfX2NoaWxkcmVuOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBpbmR4ID0g MDs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgd2hpbGUgKGluZHggJmx0OyBDVExfTUFYTkFN RSkgezxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFNMSVNUX0ZPUkVBQ0go b2lkLCBsc3AsIG9pZF9saW5rKSB7PGJyPg0KJmd0OyZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgaWYgKG9pZC0mZ3Q7b2lkX251bWJlciA9PSBuYW1lW2luZHhdKTxicj4N CiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oGJyZWFrOzxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQomZ3Q7 Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBrZXkub2lkX251bWJlciA9IG5hbWVbaW5keF07 PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgb2lkID0gUkJfRklORChzeXNj dGxfb2lkX2xpc3QsIGxzcCwgJmFtcDtrZXkpOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBpZiAob2lkID09IE5VTEwpPGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybiAoRU5PRU5UKTs8YnI+DQomZ3Q7Jmd0Ozxicj4N CiZndDsmZ3Q7IGRpZmYgLS1naXQgYS9zeXMva2Vybi92ZnNfaW5pdC5jIGIvc3lzL2tlcm4vdmZz X2luaXQuYzxicj4NCiZndDsmZ3Q7IGluZGV4IDY1NzJhOGUzNjJjMi4uNmUyZTc4YWFmNTk3IDEw MDY0NDxicj4NCiZndDsmZ3Q7IC0tLSBhL3N5cy9rZXJuL3Zmc19pbml0LmM8YnI+DQomZ3Q7Jmd0 OyArKysgYi9zeXMva2Vybi92ZnNfaW5pdC5jPGJyPg0KJmd0OyZndDsgQEAgLTUyNSw3ICs1MjUs NyBAQCB2ZnNfcmVnaXN0ZXIoc3RydWN0IHZmc2NvbmYgKnZmYyk8YnI+DQomZ3Q7Jmd0O8KgIMKg IMKgIMKgIMKgICogbnVtYmVyLjxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgKi88YnI+DQom Z3Q7Jmd0O8KgIMKgIMKgIMKgIMKgc3lzY3RsX3dsb2NrKCk7PGJyPg0KJmd0OyZndDsgLcKgIMKg IMKgIMKgU0xJU1RfRk9SRUFDSChvaWRwLCBTWVNDVExfQ0hJTERSRU4oJmFtcDtzeXNjdGxfX192 ZnMpLCBvaWRfbGluaykgezxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoFJCX0ZPUkVBQ0gob2lk cCwgc3lzY3RsX29pZF9saXN0LCBTWVNDVExfQ0hJTERSRU4oJmFtcDtzeXNjdGxfX192ZnMpKSB7 PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChzdHJjbXAob2lkcC0m Z3Q7b2lkX25hbWUsIHZmYy0mZ3Q7dmZjX25hbWUpID09IDApIHs8YnI+DQomZ3Q7Jmd0O8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3lzY3RsX3VucmVnaXN0ZXJfb2lkKG9p ZHApOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBv aWRwLSZndDtvaWRfbnVtYmVyID0gdmZjLSZndDt2ZmNfdHlwZW51bTs8YnI+DQomZ3Q7Jmd0OyBk aWZmIC0tZ2l0IGEvc3lzL3N5cy9wYXJhbS5oIGIvc3lzL3N5cy9wYXJhbS5oPGJyPg0KJmd0OyZn dDsgaW5kZXggZjg3NWQ4MzlkNDFmLi4zZjVkYTA2ZWY5NTEgMTAwNjQ0PGJyPg0KJmd0OyZndDsg LS0tIGEvc3lzL3N5cy9wYXJhbS5oPGJyPg0KJmd0OyZndDsgKysrIGIvc3lzL3N5cy9wYXJhbS5o PGJyPg0KJmd0OyZndDsgQEAgLTc2LDcgKzc2LDcgQEA8YnI+DQomZ3Q7Jmd0O8KgIMKgKiBjYW5u b3QgaW5jbHVkZSBzeXMvcGFyYW0uaCBhbmQgc2hvdWxkIG9ubHkgYmUgdXBkYXRlZCBoZXJlLjxi cj4NCiZndDsmZ3Q7wqAgwqAqLzxicj4NCiZndDsmZ3Q7wqAgI3VuZGVmIF9fRnJlZUJTRF92ZXJz aW9uPGJyPg0KJmd0OyZndDsgLSNkZWZpbmUgX19GcmVlQlNEX3ZlcnNpb24gMTQwMDA3MDxicj4N CiZndDsmZ3Q7ICsjZGVmaW5lIF9fRnJlZUJTRF92ZXJzaW9uIDE0MDAwNzE8YnI+DQomZ3Q7Jmd0 Ozxicj4NCiZndDsmZ3Q7wqAgLyo8YnI+DQomZ3Q7Jmd0O8KgIMKgKiBfX0ZyZWVCU0Rfa2VybmVs X18gaW5kaWNhdGVzIHRoYXQgdGhpcyBzeXN0ZW0gdXNlcyB0aGUga2VybmVsIG9mIEZyZWVCU0Qs PGJyPg0KJmd0OyZndDsgZGlmZiAtLWdpdCBhL3N5cy9zeXMvc3lzY3RsLmggYi9zeXMvc3lzL3N5 c2N0bC5oPGJyPg0KJmd0OyZndDsgaW5kZXggNDUxZDgzYmJlMTI1Li4zYmQ3N2NmODcyNDMgMTAw NjQ0PGJyPg0KJmd0OyZndDsgLS0tIGEvc3lzL3N5cy9zeXNjdGwuaDxicj4NCiZndDsmZ3Q7ICsr KyBiL3N5cy9zeXMvc3lzY3RsLmg8YnI+DQomZ3Q7Jmd0OyBAQCAtMzksNyArMzksOCBAQDxicj4N CiZndDsmZ3Q7wqAgI2RlZmluZcKgIMKgIMKgIMKgIF9TWVNfU1lTQ1RMX0hfPGJyPg0KJmd0OyZn dDs8YnI+DQomZ3Q7Jmd0O8KgICNpZmRlZiBfS0VSTkVMPGJyPg0KJmd0OyZndDsgLSNpbmNsdWRl ICZsdDtzeXMvcXVldWUuaCZndDs8YnI+DQomZ3Q7Jmd0OyArI2luY2x1ZGUgJmx0O3N5cy90cmVl LmgmZ3Q7PGJyPg0KJmd0OyZndDsgKyNpbmNsdWRlICZsdDtzeXMvc3lzdG0uaCZndDs8YnI+DQom Z3Q7Jmd0O8KgICNlbmRpZjxicj4NCiZndDsmZ3Q7PGJyPg0KJmd0OyZndDvCoCAvKjxicj4NCiZn dDsmZ3Q7IEBAIC0xNzMsMjAgKzE3NCwyNSBAQCBzdHJ1Y3Qgc3lzY3RsX3JlcSB7PGJyPg0KJmd0 OyZndDvCoCDCoCDCoCDCoCDCoGludMKgIMKgIMKgIMKgIMKgIMKgIMKgIGZsYWdzOzxicj4NCiZn dDsmZ3Q7wqAgfTs8YnI+DQomZ3Q7Jmd0Ozxicj4NCiZndDsmZ3Q7IC1TTElTVF9IRUFEKHN5c2N0 bF9vaWRfbGlzdCwgc3lzY3RsX29pZCk7PGJyPg0KJmd0OyZndDsgK3N0cnVjdCBzeXNjdGxfb2lk Ozxicj4NCiZndDsmZ3Q7ICs8YnI+DQomZ3Q7Jmd0OyArLyogUkIgVHJlZSBoYW5kbGluZyAqLzxi cj4NCiZndDsmZ3Q7ICtSQl9IRUFEKHN5c2N0bF9vaWRfbGlzdCwgc3lzY3RsX29pZCk7PGJyPg0K Jmd0OyZndDs8YnI+DQomZ3Q7Jmd0O8KgIC8qPGJyPg0KJmd0OyZndDvCoCDCoCogVGhpcyBkZXNj cmliZXMgb25lICZxdW90O29pZCZxdW90OyBpbiB0aGUgTUlCIHRyZWUuwqAgUG90ZW50aWFsbHkg bW9yZSBub2RlcyBjYW48YnI+DQomZ3Q7Jmd0O8KgIMKgKiBiZSBoaWRkZW4gYmVoaW5kIGl0LCBl eHBhbmRlZCBieSB0aGUgaGFuZGxlci48YnI+DQomZ3Q7Jmd0O8KgIMKgKi88YnI+DQomZ3Q7Jmd0 O8KgIHN0cnVjdCBzeXNjdGxfb2lkIHs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqBzdHJ1Y3Qg c3lzY3RsX29pZF9saXN0IG9pZF9jaGlsZHJlbjs8YnI+DQomZ3Q7Jmd0OyAtwqAgwqAgwqAgwqBz dHJ1Y3Qgc3lzY3RsX29pZF9saXN0ICpvaWRfcGFyZW50Ozxicj4NCiZndDsmZ3Q7IC3CoCDCoCDC oCDCoFNMSVNUX0VOVFJZKHN5c2N0bF9vaWQpIG9pZF9saW5rOzxicj4NCiZndDsmZ3Q7ICvCoCDC oCDCoCDCoHN0cnVjdCBzeXNjdGxfb2lkX2xpc3TCoCBvaWRfY2hpbGRyZW47PGJyPg0KJmd0OyZn dDsgK8KgIMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWRfbGlzdCogb2lkX3BhcmVudDs8YnI+DQom Z3Q7Jmd0OyArwqAgwqAgwqAgwqBSQl9FTlRSWShzeXNjdGxfb2lkKSBvaWRfbGluazs8YnI+DQom Z3Q7Jmd0OyArwqAgwqAgwqAgwqAvKiBTb3J0IGtleSBmb3IgYWxsIHNpYmxpbmdzLCBhbmQgbG9v a3VwIGtleSBmb3IgdXNlcmxhbmQgKi88YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgaW50wqAg wqAgwqAgwqAgwqAgwqAgwqAgb2lkX251bWJlcjs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKg dV9pbnTCoCDCoCDCoCDCoCDCoCDCoCBvaWRfa2luZDs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKg IMKgdm9pZMKgIMKgIMKgIMKgIMKgIMKgICpvaWRfYXJnMTs8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKg IMKgIMKgaW50bWF4X3TCoCDCoCDCoCDCoCDCoG9pZF9hcmcyOzxicj4NCiZndDsmZ3Q7ICvCoCDC oCDCoCDCoC8qIE11c3QgYmUgdW5pcXVlIGFtb25nc3QgYWxsIHNpYmxpbmdzLiAqLzxicj4NCiZn dDsmZ3Q7wqAgwqAgwqAgwqAgwqBjb25zdCBjaGFywqAgwqAgwqAgKm9pZF9uYW1lOzxicj4NCiZn dDsmZ3Q7wqAgwqAgwqAgwqAgwqBpbnTCoCDCoCDCoCDCoCDCoCDCoCDCoCgqb2lkX2hhbmRsZXIp KFNZU0NUTF9IQU5ETEVSX0FSR1MpOzxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBjb25zdCBj aGFywqAgwqAgwqAgKm9pZF9mbXQ7PGJyPg0KJmd0OyZndDsgQEAgLTE5Niw2ICsyMDIsMTkgQEAg c3RydWN0IHN5c2N0bF9vaWQgezxicj4NCiZndDsmZ3Q7wqAgwqAgwqAgwqAgwqBjb25zdCBjaGFy wqAgwqAgwqAgKm9pZF9sYWJlbDs8YnI+DQomZ3Q7Jmd0O8KgIH07PGJyPg0KJmd0OyZndDs8YnI+ DQomZ3Q7Jmd0OyArc3RhdGljIGlubGluZSBpbnQ8YnI+DQomZ3Q7Jmd0OyArY21wX3N5c2N0bF9v aWQoc3RydWN0IHN5c2N0bF9vaWQgKmEsIHN0cnVjdCBzeXNjdGxfb2lkICpiKTxicj4NCiZndDsm Z3Q7ICt7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgaWYgKGEtJmd0O29pZF9udW1iZXIgJmd0 OyBiLSZndDtvaWRfbnVtYmVyKTxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oHJldHVybiAoMSk7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgZWxzZSBpZiAoYS0mZ3Q7b2lk X251bWJlciAmbHQ7IGItJmd0O29pZF9udW1iZXIpPGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgcmV0dXJuICgtMSk7PGJyPg0KJmd0OyZndDsgK8KgIMKgIMKgIMKgZWxzZTxi cj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybiAoMCk7PGJyPg0KJmd0 OyZndDsgK308YnI+DQomZ3Q7Jmd0OyArPGJyPg0KJmd0OyZndDsgK1JCX1BST1RPVFlQRShzeXNj dGxfb2lkX2xpc3QsIHN5c2N0bF9vaWQsIG9pZF9saW5rLCBjbXBfc3lzY3RsX29pZCk7PGJyPg0K Jmd0OyZndDsgKzxicj4NCiZndDsmZ3Q7wqAgI2RlZmluZcKgIMKgIMKgIMKgIFNZU0NUTF9JTihy LCBwLCBsKcKgIMKgIMKgIChyLSZndDtuZXdmdW5jKShyLCBwLCBsKTxicj4NCiZndDsmZ3Q7wqAg I2RlZmluZcKgIMKgIMKgIMKgIFNZU0NUTF9PVVQociwgcCwgbCnCoCDCoCDCoChyLSZndDtvbGRm dW5jKShyLCBwLCBsKTxicj4NCiZndDsmZ3Q7wqAgI2RlZmluZcKgIMKgIMKgIMKgIFNZU0NUTF9P VVRfU1RSKHIsIHApwqAgwqAgKHItJmd0O29sZGZ1bmMpKHIsIHAsIHN0cmxlbihwKSArIDEpPGJy Pg0KJmd0OyZndDsgQEAgLTI3NSw3ICsyOTQsNyBAQCBUQUlMUV9IRUFEKHN5c2N0bF9jdHhfbGlz dCwgc3lzY3RsX2N0eF9lbnRyeSk7PGJyPg0KJmd0OyZndDvCoCAjZGVmaW5lwqAgwqAgwqAgwqAg U1lTQ1RMX09JRF9SQVcoaWQsIHBhcmVudF9jaGlsZF9oZWFkLCBuYnIsIG5hbWUsIGtpbmQsIGEx LCBhMiwgaGFuZGxlciwgZm10LCBkZXNjciwgbGFiZWwpIFw8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKg IMKgIMKgc3RydWN0IHN5c2N0bF9vaWQgaWQgPSB7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgXDxicj4NCiZndDsmZ3Q7wqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAub2lkX3BhcmVudCA9IChwYXJlbnRfY2hpbGRfaGVhZCkswqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgXDxicj4NCiZndDsmZ3Q7IC3CoCDCoCDCoCDCoCDC oCDCoCDCoCDCoC5vaWRfY2hpbGRyZW4gPSBTTElTVF9IRUFEX0lOSVRJQUxJWkVSKCZhbXA7aWQu b2lkX2NoaWxkcmVuKSwgXDxicj4NCiZndDsmZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC5v aWRfY2hpbGRyZW4gPSBSQl9JTklUSUFMSVpFUigmYW1wO2lkLm9pZF9jaGlsZHJlbiksIFw8YnI+ DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLm9pZF9udW1iZXIgPSAobmJyKSzC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBcPGJy Pg0KJmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC5vaWRfa2luZCA9IChraW5kKSzC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFw8 YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLm9pZF9hcmcxID0gKGExKSzC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oFw8YnI+DQomZ3Q7Jmd0Ozxicj4NCjxicj4NCjwvYmxvY2txdW90ZT48L2Rpdj4NCg== --000000000000f7ae8605ea4ece83--